`volatile` 在线程之间同步变量 [英] `volatile` to sync variable between threads

查看:58
本文介绍了`volatile` 在线程之间同步变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个从两个线程访问的变量 int foo.假设我没有竞争条件问题(访问受互斥锁保护,所有操作都是原子的,或者任何其他保护竞争条件的方法),仍然存在寄存器缓存"问题(因为没有更好的名称),其中编译器可能会假设如果变量被读取两次而没有被写入,它是相同的值,因此可能会优化"以下内容:

I have a variable int foo that is accessed from two threads. Assuming I have no race-condition issues (access is protected by a mutex, all operations are atomic, or whatever other method to protect from race conditions), there is still the issue of "register caching" (for lack of a better name), where the compiler may assume that if the variable is read twice without being written in between, it is the same value, and so may "optimize" away things like:

while(foo) { // <-may be optimized to if(foo) while(1)
  do-something-that-doesn't-involve-foo;
}

if(foo) // becomes something like (my assembly is very rusty): mov ebx, [foo]; cmp ebx, 0; jz label;
  do-something-that-doesn't-involve-foo;
do-something-else-that-doesn't-involve-foo;
if(foo) // <-may be optimized to jz label2;
  do-something;

foo 标记为 volatile 能解决这个问题吗?来自一个线程的更改是否保证会到达另一个线程?

does marking foo as volatile solve this issue? Are changes from one thread guaranteed to reach the other thread?

如果没有,还有什么其他方法可以做到这一点?我需要一个适用于 Linux/Windows 的解决方案(可能是单独的解决方案),没有 C++11.

If not, what other way is there to do this? I need a solution for Linux/Windows (possibly separate solutions), no C++11.

推荐答案

您需要的是内存屏障.

MemoryBarrier();

__sync_synchronize();

我把有趣的部分加粗了,这里是维基文章的链接(http://en.wikipedia.org/wiki/Memory_barrier#cite_note-1)和相关参考文献(http://www.rdrop.com/users/paulmck/scalability/paper/whymb.2010.07.23a.pdf)

I've bolded the interesting part and here's the link to the wiki article (http://en.wikipedia.org/wiki/Memory_barrier#cite_note-1) and the associated reference (http://www.rdrop.com/users/paulmck/scalability/paper/whymb.2010.07.23a.pdf)

这是您另一个问题的答案(来自维基百科):在 C 和 C++ 中, volatile 关键字旨在允许 C 和 C++ 程序直接访问内存映射 I/O.内存映射 I/O 通常要求源代码中指定的读取和写入按照指定的确切顺序进行,没有遗漏.编译器对读取和写入的遗漏或重新排序会破坏程序和由内存映射 I/O 访问的设备之间的通信.C 或 C++ 编译器不得对易失性存储器位置的读取和写入重新排序,也不得省略对易失性存储器位置的读取或写入.关键字 volatile 不能保证强制缓存一致性的内存屏障.因此,单独使用volatile"不足以在所有系统和处理器上使用变量进行线程间通信[1]

Here's the answer to your other question (from wikipedia): In C and C++, the volatile keyword was intended to allow C and C++ programs to directly access memory-mapped I/O. Memory-mapped I/O generally requires that the reads and writes specified in source code happen in the exact order specified with no omissions. Omissions or reorderings of reads and writes by the compiler would break the communication between the program and the device accessed by memory-mapped I/O. A C or C++ compiler may not reorder reads and writes to volatile memory locations, nor may it omit a read or write to a volatile memory location. The keyword volatile does not guarantee a memory barrier to enforce cache-consistency. Therefore the use of "volatile" alone is not sufficient to use a variable for inter-thread communication on all systems and processors[1]

看看这个,它提供了关于这个主题的很好的解释:http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2

Check this one out, it provides great explanations on the subject: http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-1-of-2 http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2

这篇关于`volatile` 在线程之间同步变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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