将对象传递到两个std ::线程

Passing an object to two std::threads

本文关键字:两个 std 线程 对象      更新时间:2023-10-16

如果我创建了一个将由两个不同的std ::线程访问的对象,那么当我创建对象或将其传递给线程时,我需要做任何特殊的规定吗?

例如:

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。我应该做不同的事情吗?

您在 alpha.x上具有竞赛条件,因为当另一个读取/写入其值时,这两个线程都可以写入。您可以通过将x的类型更改为std::atomic<int>或使用Mutex的读/写入访问来解决此问题。

如果要通过多个线程访问对象,则必须为同步提供规定。在您的情况下,将变量x声明为原子是足够的:

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

这将确保任何递增" x"的功能实际使用原子fetch_and_add()方法。这可以确保每个递增变量" x"的线程将获得x。

的唯一增量值

在您发布的代码中,如果执行恰好交织在一起,则两个线程对于x的值很可能会得到1的值。