我有一个多线程的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/