如果有两个线程访问全局变量,那么许多教程都说使变量volatile变为阻止编译器将变量缓存在寄存器中,从而无法正确更新.但是,访问共享变量的两个线程是通过互斥锁来调用保护的东西不是吗?但是在这种情况下,在线程锁定和释放互斥锁之间,代码处于一个关键部分,只有那个线程可以访问变量,在这种情况下变量不需要是volatile?
那么多线程程序中volatile的用途/目的是什么?
从我从Herb Sutter和其他人那里读到的内容,您会认为volatile并发编程是完全正交的概念,至少就C/C++而言.
但是,在GCC 实现中,所有std::atomic的成员函数都有volatile限定符.安东尼威廉姆斯的实施也是如此std::atomic.
那么什么是交易,我的atomic<>变量需要volatile与否?
在进行并发编程时,我需要告诉编译器/优化器它可能不会缓存变量的值,也就是说,它可能随时改变.我目前正在使用volatile关键字,但我想知道这是否真的正确?
该标准规定易失性访问可能不会重新排序,如IO调用,但我实际上根本不关心排序,我关心内容.标准中是否有任何内容可以澄清每次访问时都必须加载volatile ?
更重要的是,在这种情况下,我甚至不关心它是否重新排序.我使用栅栏/原子操作来保证我需要的任何订单.
另外,在C++ 0x中,将使用atomic<T>自动给出相同的加载保证(如果我调用load)?或者我是否必须将变量标记为volatile?
重要我对锁定一段代码不感兴趣.我已经使用栅栏来确保订购.我正在谈论对单个基础的访问int(在我正在的平台上假设原子).也就是说,我需要专门告诉GCC优化器a不应该以任何方式缓存变量,因此如果在循环中使用,则必须每次都调用相应的加载指令.
如果volatile不正确,这样做的正确方法是什么?我目前正在使用GCC而不是使用C++ 0x.
答案:基本上预先C++ 0x没有什么可以强制重新加载,并且在某些架构上重新加载甚至可能不够.volatile强烈暗示变量应该重新加载,并且可以在许多体系结构上工作,虽然不是正确的答案,但是目前唯一可用的选项.
关于volatile的问题已经有很多了,但是我没有看到一个特别针对我要问的问题:为并发访问标记变量的正确方法.
可能重复:
何时使用volatile多线程?
我有两个引用相同的线程boost::shared_ptr:
boost::shared_ptr<Widget> shared;
Run Code Online (Sandbox Code Playgroud)
在线程正在旋转,等待另一个线程重置boost::shared_ptr:
while(shared)
boost::thread::yield();
Run Code Online (Sandbox Code Playgroud)
在某些时候,另一个线程会调用:
shared.reset();
Run Code Online (Sandbox Code Playgroud)
我的问题是我是否需要声明共享指针volatile以防止编译器优化shared.operator bool()对循环的调用并且从不检测更改?我知道如果我只是循环变量,等待它达到0我需要volatile,但我不确定是否boost::shared_ptr以这样的方式实现它是不必要的.
编辑:我完全清楚条件变量可以用来以不同的方式解决这个问题.但在这种情况下,繁忙的循环非常罕见,并且争用条件变量的锁定是我们宁愿不会产生的开销.