C++ volatile关键字,具有由函数访问的全局共享变量

jbu*_*jbu 5 c++ concurrency multithreading volatile

我有一个多线程C++应用程序.

现在我知道对于全局共享变量,在检查变量状态时应该在某些情况下使用volatile,否则编译器可能会认为变量的值永远不会改变(在该线程中).

但是,如果不是检查变量的状态而是调用返回变量值的方法,该怎么办?例如:

static int num = 0;

...

void foo()
{
   while(getNum() == 0)
   {
      // do something (or nothing)
   }
}
Run Code Online (Sandbox Code Playgroud)

我还需要将num变为volatile变量吗?或者编译器是否认识到,因为我正在使用一种方法来访问该变量num,所以它不会缓存结果?

有人有任何想法吗?

提前致谢,

〜朱利安

编辑:在我的while循环中我删除了睡眠调用并用通用的东西替换它,例如注释做某事(或什么都没有)

Pot*_*ter 4

不,volatile只要您进行必要的同步,就永远不需要。

调用线程库同步函数,无论它们在您的平台上是什么,都应该注意使本地“缓存”值无效并使编译器重新加载全局变量。

在这种特殊情况下,sleep很可能会产生这样的效果,但无论如何它都不是一个好的实现。上应该有一个条件变量num,用 setter 函数保护它,并让 setter 函数向 发送信号foo

至于具体问题,函数是否隐藏优化的访问是极其依赖于实现和情况的。最好的选择是在编译器的单独调用中编译 getter 函数,但即使如此,也无法保证不会发生过程间优化。例如,某些平台可能会将IR代码放入文件中.o并在“链接器”阶段执行代码生成。

免责声明。

上面关键词:1.只要你做好了必要的同步,2.就可能有这样的效果

1:sleep或者空的忙循环都不是“必要的同步”。这不是编写多线程程序的正确方法。因此,在这种情况下可能需要 volatility。

2:是的,sleep可能不被算作I/O函数的实现,甚至可能被标记为纯粹且无副作用。在这种情况下,volatile全球就很有必要了。然而,我怀疑是否真的有任何分布式实现会打破sleep这样的循环,因为不幸的是它们很常见。

  • +1:“易失性”*不是*适当的多线程同步结构的替代品。 (5认同)