将对象传递给两个std :: threads

时间:2015-05-08 14:42:51

标签: c++ multithreading

如果我创建一个将由两个不同的std :: threads访问的对象,在创建对象或将其传递给线程时是否需要做出任何特殊规定?

例如:

class Alpha
{
public:
    int x;
};

void Foo(Alpha* alpha)
{
    while (true)
    {
        alpha->x++;
        std::cout << "Foo: alpha.x = " << alpha->x << std::endl;
    }
}

void Bar(Alpha* alpha)
{
    while (true)
    {
        alpha->x++;
        std::cout << "Bar: alpha.x = " << alpha->x << std::endl;
    }
}

int main(int argc, char * argv[])
{
    Alpha alpha;
    alpha.x = 0;
    std::thread t1(Foo, &alpha);
    std::thread t2(Bar, &alpha);
    t1.join();
    t2.join();

    return 0;
}

这编译很好,似乎也运行正常。但我没有明确地告诉我的程序,alpha需要由两个不同的线程访问。我应该这样做吗?

2 个答案:

答案 0 :(得分:4)

alpha.x上有竞争条件,因为两个线程可能会在另一个读取/写入其值时写入。您可以通过将x的类型更改为std::atomic<int>或使用互斥锁保护读/写访问权来解决此问题。

答案 1 :(得分:3)

如果一个对象将被多个线程访问,那么您必须为同步做好准备。在您的情况下,将变量x声明为原子就足够了:

#include <atomic>

class Alpha
{
public:
    std::atomic<int> x;
};

这将保证任何增加&#34; x&#34;实际上将使用原子fetch_and_add()方法。这保证了每个线程增加变量&#34; x&#34;将获得x的唯一递增值。

在您发布的代码中,如果执行交错恰到好处,则两个线程极有可能获得x的值。