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

Rei*_*eid 5 c++ multithreading timer boost-asio

我有一个跨平台的c ++程序,我正在使用boost库来创建一个异步计时器.
我有一个全局变量:

bool receivedInput = false;
Run Code Online (Sandbox Code Playgroud)

一个线程等待并处理输入

string argStr;
while (1) 
{
     getline(cin, argStr);
     processArguments(argStr);
     receivedInput = true;
}
Run Code Online (Sandbox Code Playgroud)

另一个线程运行一个计时器,每10秒调用一次回调.在该回调中,我检查是否收到了消息

if (receivedInput)
{
    //set up timer to fire again in 10 seconds
    receivedInput = false;
}
else
    exit(1);
Run Code Online (Sandbox Code Playgroud)

这样安全吗?对于线程2中的读取,我认为无关紧要,因为条件将评估为true或false.但我不确定如果两个线程同时尝试设置receivedInput会发生什么.我也把我的计时器比我期望接收输入的时间长3倍,所以我不担心比赛情况.

编辑:为了解决这个问题,我在读取receivedInput时设置了receiveInput和boost :: shared_lock时使用了boost :: unique_lock.我在这里用了一个例子

Ada*_*man 5

这基本上是不安全的.线程1写入truereceivedInput,不保证线程2将看到新值.例如,编译器可以优化您的代码,receivedInput对它在用作if条件时的值进行某些假设或将其缓存在寄存器中,因此您无法保证在if时实际读取主内存.评估条件.此外,编译器和CPU都可以更改读取和写入的顺序以进行优化,例如true可以在receivedInput之前getLine()和之前写入processArguments().

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

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

您需要内存障碍或适当的同步机制才能按预期工作.