【发布时间】:2010-12-30 17:20:10
【问题描述】:
在今天的code review 中,我偶然发现了以下代码(为发布而稍作修改):
while (!initialized)
{
// The thread can start before the constructor has finished initializing the object.
// Can lead to strange behavior.
continue;
}
这是在新线程中运行的前几行代码。在另一个线程中,一旦初始化完成,它会将initialized 设置为true。
我知道优化器可以把它变成一个无限循环,但是避免这种情况的最好方法是什么?
-
volatile- considered harmful - 调用
isInitialized()函数而不是直接使用变量- 这会保证内存屏障吗?如果函数声明为inline会怎样?
还有其他选择吗?
编辑:
应该早点提到这一点,但这是需要在 Windows、Linux、Solaris 等平台上运行的可移植代码。我们主要使用 Boost.Thread 作为可移植线程库。
【问题讨论】:
-
为什么不只是......在初始化完成之前不启动线程?即,将启动新线程的代码移动到另一个线程的初始化代码的末尾。
-
@Karl 是的,最好的解决方案是完全避免这种情况。不过,我仍然对一般问题的答案感兴趣。
-
糟糕,这不是一个精确副本。这不是
exit_now标志,因此您希望std::atomic<bool>至少带有memory_order_acquire。mo_relaxed在这里 not 就足够了,就像exit_now标志一样。关闭后才注意到差异。从标题来看,人们可能不会考虑用其他方法来解决初始化问题(除了 spin-wait)。
标签: c++ multithreading thread-safety compiler-optimization