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

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

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

static int num = 0;

...

void foo()
{
   while(getNum() == 0)
   {
      // do something (or nothing)
   }
}

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

任何人有任何想法吗?

提前致谢,

〜朱利安

编辑:在我的while循环中,我删除了sleep调用,并将其替换为诸如评论之类的通用名称,以执行某项操作(或不执行任何操作)

最佳答案

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

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

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

对于特定的问题,该功能是否对优化隐藏了访问权限,这在很大程度上取决于实现和情况。最好的选择是在单独的编译器调用中编译getter函数,但是即使那样,也无法保证不会发生过程间优化。例如,某些平台可能会将IR代码放入.o文件中,并在“链接器”阶段执行代码生成。

免责声明。

上面的关键字:1. (只要您正在执行必要的同步)和2. 可能具有这样的效果。

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

2:是的,实现I/O功能可能不计算sleep,甚至可以将其标记为纯净的且没有副作用。在这种情况下,必须在全局上使用volatile。但是,我很怀疑是否有任何实现会破坏像sleep这样的循环,因为不幸的是它们很常见。

关于具有函数访问的全局共享变量的C++ volatile关键字,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3650267/

10-10 12:47
查看更多