如果两个线程同时访问同一个bool变量,会发生什么情况? [英] What could happen if two threads access the same bool variable at the same time?

查看:994
本文介绍了如果两个线程同时访问同一个bool变量,会发生什么情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆