c++ - 一个线程设置成员,而另一个循环遍历它 - 这是线程不安全的吗?

标签 c++ multithreading optimization

我刚刚在我们的代码库中发现了以下结构(在示例中进行了简化):

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_keepGoingm_doAdditionalStuff这样你就可以同步了。

关于c++ - 一个线程设置成员,而另一个循环遍历它 - 这是线程不安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54790992/

相关文章:

ios - 优化 CoreGraphics 功能/替代方案

c++ - 在 Release模式下编译时,大量嵌套循环会导致链接器无休止地运行吗?

c++ - SFML 无法加载图像

c# - 非阻塞并行(TPL)的互锁使用问题

java - 关闭 TCP 线程服务器

java - JVM按函数管理类代码吗?拆分大型决策函数对内存使用有效吗?

c++ - C++中的临时对象如何影响效率?

c++ - 初始化空 std::vector C++ 时出现段错误

c++ - 将动态分配的指针数组调整为类

c++ - 如何避免在 C++ 中进行一些繁重的处理时阻塞线程?