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循环中我删除了睡眠调用并用通用的东西替换它,例如注释做某事(或什么都没有)
不,volatile
只要您进行必要的同步,就永远不需要。
调用线程库同步函数,无论它们在您的平台上是什么,都应该注意使本地“缓存”值无效并使编译器重新加载全局变量。
在这种特殊情况下,sleep
很可能会产生这样的效果,但无论如何它都不是一个好的实现。上应该有一个条件变量num
,用 setter 函数保护它,并让 setter 函数向 发送信号foo
。
至于具体问题,函数是否隐藏优化的访问是极其依赖于实现和情况的。最好的选择是在编译器的单独调用中编译 getter 函数,但即使如此,也无法保证不会发生过程间优化。例如,某些平台可能会将IR代码放入文件中.o
并在“链接器”阶段执行代码生成。
上面关键词:1.只要你做好了必要的同步,2.就可能有这样的效果。
1:sleep
或者空的忙循环都不是“必要的同步”。这不是编写多线程程序的正确方法。因此,在这种情况下可能需要 volatility。
2:是的,sleep
可能不被算作I/O函数的实现,甚至可能被标记为纯粹且无副作用。在这种情况下,volatile
全球就很有必要了。然而,我怀疑是否真的有任何分布式实现会打破sleep
这样的循环,因为不幸的是它们很常见。