Cha*_*onX 2 c++ optimization multithreading
我刚刚在代码库中发现了以下构造(在示例中简化):
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;
}
Run Code Online (Sandbox Code Playgroud)
有多个线程,一个呼叫,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
}
}
Run Code Online (Sandbox Code Playgroud)
我的怀疑是否正确?
如果你有读者和作者(或多个作者;除了读者之外的任何东西)在多个线程中访问同一个变量,你需要将该变量设为原子或使用锁(或其他同步原语).否则,您将进行数据竞争,并且您的程序具有未定义的行为.
你的怀疑是正确的.如果没有某种同步机制,您无法在多个线程中写入和读取相同的变量.这样做是数据竞争,是未定义的行为.
在这种情况下你可以做的是使用一个std::atomic<bool>for m_keepGoing,m_doAdditionalStuff这样你就可以进行同步.