If I create an object which is going to be accessed by two different std::threads, do I need to make any special provisions when I create the object or pass it to the threads?
如果我创建一个将由两个不同的std :: threads访问的对象,在创建对象或将其传递给线程时是否需要做出任何特殊规定?
For example:
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;
}
This compiles fine, and seems to run fine too. But I haven't explicitly told my program that alpha
needs to be accessed by two different threads. Should I be doing this differently?
编译很好,似乎运行良好。但我没有明确告诉我的程序alpha需要由两个不同的线程访问。我应该这样做吗?
2 个解决方案
#1
If an object is going to be accessed by multiple threads, then you must make provisions for synchronization. In your case, it will suffice to declare the variable x as an atomic:
如果一个对象将被多个线程访问,那么您必须为同步做出规定。在您的情况下,将变量x声明为原子就足够了:
#include <atomic>
class Alpha
{
public:
std::atomic<int> x;
};
This will guarantee that any function which increments "x" will actually use the atomic fetch_and_add() method. This guarantees that each thread that increments the variable "x" will get a unique incremented value of x.
这将保证增加“x”的任何函数实际上将使用原子fetch_and_add()方法。这保证了增加变量“x”的每个线程将获得x的唯一递增值。
In the code you have posted, it is extremely possible that both threads will get a value of 1 for x if the executions interleave just right.
在您发布的代码中,如果执行交错恰到好处,则两个线程极有可能获得x的值1。
#2
You have race condition on alpha.x
, as both threads may write when the other read/write its value. You may fix that by changing type of x
into std::atomic<int>
or by using protecting read/write access by mutex.
你在alpha.x上有竞争条件,因为两个线程可能会在另一个读取/写入其值时写入。您可以通过将x的类型更改为std :: atomic
#1
If an object is going to be accessed by multiple threads, then you must make provisions for synchronization. In your case, it will suffice to declare the variable x as an atomic:
如果一个对象将被多个线程访问,那么您必须为同步做出规定。在您的情况下,将变量x声明为原子就足够了:
#include <atomic>
class Alpha
{
public:
std::atomic<int> x;
};
This will guarantee that any function which increments "x" will actually use the atomic fetch_and_add() method. This guarantees that each thread that increments the variable "x" will get a unique incremented value of x.
这将保证增加“x”的任何函数实际上将使用原子fetch_and_add()方法。这保证了增加变量“x”的每个线程将获得x的唯一递增值。
In the code you have posted, it is extremely possible that both threads will get a value of 1 for x if the executions interleave just right.
在您发布的代码中,如果执行交错恰到好处,则两个线程极有可能获得x的值1。
#2
You have race condition on alpha.x
, as both threads may write when the other read/write its value. You may fix that by changing type of x
into std::atomic<int>
or by using protecting read/write access by mutex.
你在alpha.x上有竞争条件,因为两个线程可能会在另一个读取/写入其值时写入。您可以通过将x的类型更改为std :: atomic