通过引用传递对象和多线程

时间:2017-02-09 23:08:12

标签: c++ multithreading pass-by-reference

我有一个小问题,想知道是否有人可以提供帮助。我试图以最简单的方式证明我的问题。我试图通过引用传递一个对象多个线程。每个线程调用“doSomething”,它是属于对象“Example”的成员函数。 “doSomething”函数应该递增计数器。我的gcc版本是4.4.7

问题:

为什么变量“counter”的值不会增加,尽管我通过引用传递了对象的线程函数。

代码:

#include <iostream>
#include <thread>

class Exmaple {
    private:
        int counter;

    public:
            Exmaple() { 
            counter = 0;
        }    

        void doSomthing(){
            counter++;
        }

        void print() {
            std::cout << "value from A: " << counter << std::endl;
        }

};

// notice that the object is passed by reference
void thread_task(Exmaple& o) {
    o.doSomthing();
    o.print();
}    

int main()
{
    Exmaple b;
    while (true) {
        std::thread t1(thread_task, b);
        t1.join();
    }    
    return 0;
}

输出:

value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1

3 个答案:

答案 0 :(得分:5)

while (true) {
    std::thread t1(thread_task, b);
    t1.join();
}  

你需要知道两件事:

  • 使用std::ref传递参考。
  • 无限循环是C ++中未定义的行为;

下面的工作示例:

#include <iostream>
#include <thread>

class Exmaple {
    private:
        int counter;

    public:
            Exmaple() { 
            counter = 0;
        }    

        void doSomthing(){
            counter++;
        }

        void print() {
            std::cout << "value from A: " << counter << std::endl;
        }

};

// notice that the object is passed by reference
void thread_task(Exmaple& o) {
    o.doSomthing();
    o.print();
}    

int main()
{
    Exmaple b;
    for(int i =0; i < 10; i++) {
        std::thread t1(thread_task, std::ref(b));
        t1.join();
    }    
    return 0;
}

输出:

value from A: 1
value from A: 2
value from A: 3
value from A: 4
value from A: 5
value from A: 6
value from A: 7
value from A: 8
value from A: 9
value from A: 10

Live

虽然走得更远,但您还应该考虑数据竞争

答案 1 :(得分:4)

我对多线程不是很熟悉,但是您通过值b向线程传递,而不是通过引用传递。然后b的值通过引用传递给thread_task,因此值始终为1.

根据the documentation,你必须编写你的线程,以便通过引用传递对象:

std::thread t1(thread_task, std::ref(b));

答案 2 :(得分:0)

请注意,在std::thread t1(thread_task, b)中,您将b按值传递给std::thread的构造函数(因为您在此处调用构造函数,而不是直接调用thread_task)。解决方案可以是通过b - 对象包装std::ref,也可以更改代码以传递指针:

void thread_task(Exmaple* o) {
    o->doSomthing();
    o->print();
}

int main()
{
    Exmaple b;
    while (true) {
        std::thread t1(thread_task, &b);
        t1.join();
    }
    return 0;
}