我刚刚在我们的代码库中发现了以下结构(在示例中进行了简化):
class SomeClass
{
public:
void setKeepGoing(bool b) { m_keepGoing = b; }
void setDoAdditionalStuff(bool b) { m_doAdditionalStuff = b; }
void someLoop()
{
while(m_keepGoing)
{
//Do something
bool doMore = m_doAdditionalStuff;
if (doMore)
//Do more things
}
}
private:
bool m_keepGoing;
bool m_doAdditionalStuff;
}
有多个线程,一个调用someLoop()
而其他人则调用setKeepGoing()
和/或 setDoAdditionalStuff()
.
现在我的直觉是,这是可怕的线程不安全。编译器可以很好地优化阅读 m_doAdditionalStuff
在循环内部(因为它在那里没有改变)甚至 m_keepGoing
(因为那里也没有改变)有效地导致代码行为如下:
void someLoop()
{
if (!m_keepGoing)
return;
bool doMore = m_doAdditionalStuff;
while(true)
{
//Do something
if (doMore)
//Do more things
}
}
我的怀疑是否正确?
最佳答案
你的怀疑是正确的。如果没有某种同步机制,您不能在多个线程中写入和读取同一个变量。这样做是一场数据竞赛,是未定义的行为。
在这种情况下你可以做的是使用 std::atomic<bool>
对于 m_keepGoing
和 m_doAdditionalStuff
这样你就可以同步了。
关于c++ - 一个线程设置成员,而另一个循环遍历它 - 这是线程不安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54790992/