gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:26:19 30 4
gpt4 key购买 nike

我有一个跨平台的 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/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com