c++ - `volatile` 在线程之间同步变量

标签 c++ c multithreading volatile

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

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 可以解决这个问题吗?来自一个线程的更改是否保证会到达另一个线程?

如果不行,还有什么方法可以做到这一点?我需要一个适用于 Linux/Windows 的解决方案(可能是单独的解决方案),而不是 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 )

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

看看这个,它对这个主题提供了很好的解释: 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

关于c++ - `volatile` 在线程之间同步变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18135116/

相关文章:

c++ - std::string 和 std::wstring 的 wdk ddk 编译器问题

c++ - 具有浮点值和转换的算术运算的错误结果 - 差异很大,我想这不是不准确值的情况 (429497)?

C - 将一个文件夹内容复制到另一个

java - 测试线程优先级。为什么在某些情况下低优先级线程更快?

python - 在其他线程/进程正在输出时接收标准输入

c++ - GTKmm3 (GTK+ 3 C++) 编译但在运行时抛出 GLib-GIO-CRITICAL 错误

c++ - 是什么导致编译库在内部存储其构建命令?

c++ - QextSerialPort - 检测断开连接

在 C 中创建和初始化用户定义类型的数组

c - glibc 在 C 中使用 posix 线程时检测到 free()