c++ - 如果两个线程同时访问同一个 bool 变量会发生什么?

标签 c++ multithreading timer boost-asio

我有一个跨平台的 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() 之前写入 receivedInputprocessArguments()

此外,依靠计时进行同步是一个非常糟糕的主意,因为通常您无法保证每个线程在给定时间间隔内获得的 CPU 时间量,或者它是否会在给定时间间隔内被调度.

一个常见的错误是认为使 receivedInput volatile 在这里可能有所帮助。事实上,volatile 保证值实际上是读/写到主内存(而不是例如缓存在寄存器中)并且变量的读写是相对于彼此排序的。但是,它不保证 volatile 变量的读取和写入相对于其他指令是有序的。

您需要内存屏障或适当的同步机制才能使其按预期工作。

关于c++ - 如果两个线程同时访问同一个 bool 变量会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8409106/

相关文章:

c++ - 命名空间中变量的未解析外部符号

c++ - 在 VS2010 项目中包含文件

c++ - 无法在 VS 2015 中编译 CUDA 代码

python - 将 win32com 与多线程一起使用

Java——等待方法未退出

java - 如何在鼠标退出事件上启动定时器并在鼠标输入事件上停止同一个定时器?

java - 如何在 Java 中正确处理定时器?

.net - .NET中的高分辨率计时器

c++ - 在 typedef 结构体上使用 sizeof 运算符

java - 是否有原因导致线程仅在我强制调试时才执行?