我有一个跨平台的 C++ 程序,我在其中使用 boost 库创建一个异步计时器。
我有一个全局变量:
bool receivedInput = false;
一个线程等待并处理输入
string argStr;
while (1)
{
getline(cin, argStr);
processArguments(argStr);
receivedInput = true;
}
另一个线程运行一个计时器,每 10 秒调用一次回调。在该回调中,我检查是否收到消息
if (receivedInput)
{
//set up timer to fire again in 10 seconds
receivedInput = false;
}
else
exit(1);
这样安全吗?对于线程 2 中的读取,我认为这无关紧要,因为条件将评估为 true 或 false。但是我不确定如果两个线程同时尝试设置 receivedInput 会发生什么。我还让我的计时器比我期望接收输入的时间长 3 倍,所以我不担心竞争条件。
编辑: 为了解决这个问题,我在设置 receivedInput 时使用了 boost::unique_lock,在读取 receivedInput 时使用了 boost::shared_lock。我使用了 here 中的示例
最佳答案
这从根本上来说是不安全的。在线程 1 将 true
写入 receivedInput
后,不能保证线程 2 会看到新值。例如,编译器可能会优化您的代码,在将其用作 if 条件或将其缓存在寄存器中时对 receivedInput
的值做出某些假设,因此您无法保证主内存会实际上在评估 if 条件时被读取。此外,编译器和 CPU 都可能会更改读取和写入的顺序以进行优化,例如 true
可能会在 getLine()
之前写入 receivedInput
和 processArguments()
。
此外,依靠计时进行同步是一个非常糟糕的主意,因为通常您无法保证每个线程在给定时间间隔内获得的 CPU 时间量,或者它是否会在给定时间间隔内被调度.
一个常见的错误是认为使 receivedInput
volatile
在这里可能有所帮助。事实上,volatile
保证值实际上是读/写到主内存(而不是例如缓存在寄存器中)并且变量的读写是相对于彼此排序的。但是,它不保证 volatile
变量的读取和写入相对于其他指令是有序的。
您需要内存屏障或适当的同步机制才能使其按预期工作。
关于c++ - 如果两个线程同时访问同一个 bool 变量会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8409106/