我已经阅读了一段时间,以便更好地了解使用现代(多核)CPU 进行多线程编程时发生的情况。但是,当我阅读本文时,我注意到“显式编译器障碍”部分中的以下代码,它没有将 volatile 用于IsPublished
全局。
#define COMPILER_BARRIER() asm volatile("" ::: "memory")
int Value;
int IsPublished = 0;
void sendValue(int x)
{
Value = x;
COMPILER_BARRIER(); // prevent reordering of stores
IsPublished = 1;
}
int tryRecvValue()
{
if (IsPublished)
{
COMPILER_BARRIER(); // prevent reordering of loads
return Value;
}
return -1; // or some other value to mean not yet received
}
问题是,在IsPublished
这里省略 volatile 是否安全?许多人提到“volatile”关键字与多线程编程无关,我同意他们的看法。但是,在编译器优化期间可以应用“恒定折叠/传播”,并且如wiki 页面所示,如果编译器不太了解谁可以if (IsPublished)
更改. 我在这里错过或误解了什么吗?if (false)
IsPublished
内存屏障可以防止 CPU 的编译器排序和乱序执行,但正如我在上一段中所说,我仍然需要volatile
避免“恒定折叠/传播”,这是一种危险的优化,尤其是使用全局变量作为标志无锁码?