如果两个线程同时访问同一个bool变量,会发生什么情况? [英] What could happen if two threads access the same bool variable at the same time?
问题描述
我有一个跨平台的c ++程序,我在其中使用Boost库来创建一个异步计时器.
我有一个全局变量:
I have a cross platform c++ program where I'm using the boost libraries to create an asynchronous timer.
I have a global variable:
bool receivedInput = false;
一个线程等待并处理输入
One thread waits for and processes input
string argStr;
while (1)
{
getline(cin, argStr);
processArguments(argStr);
receivedInput = true;
}
另一个线程运行一个计时器,该计时器每10秒调用一次回调.在该回调中,我检查是否已收到消息
The other thread runs a timer where a callback gets called every 10 seconds. In that callback, I check to see if I've received a message
if (receivedInput)
{
//set up timer to fire again in 10 seconds
receivedInput = false;
}
else
exit(1);
这样安全吗?对于线程2中的读操作,我认为这没有关系,因为条件的评估结果为true或false.但是我不确定如果两个线程尝试同时设置receiveInput会发生什么.我还使计时器的时间比预期输入的时间长了3倍,因此我不必担心比赛情况.
So is this safe? For the read in thread 2, I think it wouldn't matter since the condition will evaluate to either true or false. But I'm unsure what would happen if both threads try to set receivedInput at the same time. I also made my timer 3x longer than the period I expect to receive input so I'm not worried about a race condition.
为了解决这个问题,当我设置了receivedInput时,我使用了boost :: unique_lock;当我读取了receivedInput时,我使用了boost :: shared_lock.我使用了此处
To solve this I used boost::unique_lock when I set receivedInput and boost::shared_lock when I read receivedInput. I used an example from here
推荐答案
这从根本上是不安全的.线程1将true
写入receivedInput
后,不能保证线程2将看到新值.例如,当receivedInput
的值用作if条件或将其缓存在寄存器中时,编译器可能会对receivedInput
的值做出某些假设,从而优化您的代码,因此您不能保证实际上可以在主存储器中读取主存储器.评估条件条件的时间.此外,编译器和CPU都可以更改读取和写入的顺序以进行优化,例如,true
可以在getLine()
和processArguments()
之前写入receivedInput
.
This is fundamentally unsafe. After thread 1 has written true
to receivedInput
it isn't guaranteed that thread 2 will see the new value. For example, the compiler may optimize your code making certain assumptions about the value of receivedInput
at the time it is used as the if condition or caching it in a register, so you are not guaranteed that main memory will actually be read at the time the if condition is evaluated. Also, both compiler and CPU may change the order of reads and writes for optimization, for example true
may be written to receivedInput
before getLine()
and processArguments()
.
此外,依靠时序进行同步是一个非常糟糕的主意,因为通常您无法保证每个线程在给定的时间间隔内将获得的CPU时间量,还是无法在预定的时间间隔内进行调度
Moreover, relying on timing for synchronization is a very bad idea since often you have no guarantees as to the amount of CPU time each thread will get in a given time interval or whether it will be scheduled in a given time interval at all.
一个常见的错误是认为制作receivedInput
volatile
可能会有所帮助.实际上,volatile
保证值实际上被读/写到主存储器(而不是例如被缓存在寄存器中),并且变量的读和写相对于彼此排序.但是,它不能保证volatile
变量的读取和写入相对于其他指令是顺序进行的.
A common mistake is to think that making receivedInput
volatile
may help here. In fact, volatile
guarantees that values are actually read/written to the main memory (instead of for example being cached in a register) and that reads and writes of the variable are ordered with respect to each other. However, it does not guarantee that the reads and writes of the volatile
variable are ordered with respect to other instructions.
您需要内存障碍或适当的同步机制,以使其按预期工作.
You need memory barriers or a proper synchronization mechanism for this to work as you expect.
这篇关于如果两个线程同时访问同一个bool变量,会发生什么情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!