c++ - 在这种情况下 'double checked locking pattern' 对 std::mutex 有用吗?

标签 c++ c++11

我经常遇到这种线程安全结构的设计。如下面的version1,一个线程可能很少调用foo1::add_data(),而另一个线程经常调用foo1::get_result()。出于优化的目的,我认为它可以使用原子来应用双重检查锁定模式 (DCLP),如 version2 所示。这种情况还有其他更好的设计吗?还是可以对其进行改进,例如使用 std::memory_order 访问 atomic?

版本 1:

class data {};
class some_data {};
class some_result {};

class foo1
{
public:
    foo1() : m_bNeedUpdate(false) {}

    void add_data(data n)
    {
        std::lock_guard<std::mutex> lock(m_mut);

        // ... restore new data to m_SomeData

        m_bNeedUpdate = true;
    }

    some_result get_result() const
    {
        {
            std::lock_guard<std::mutex> lock(m_mut);
            if (m_bNeedUpdate)
            {
                // ... process mSomeData and update m_SomeResult

                m_bNeedUpdate = false;
            }
        }
        return m_SomeResult;
    }

private:
    mutable std::mutex  m_mut;
    mutable bool        m_bNeedUpdate;
    some_data           m_SomeData;

    mutable some_result m_SomeResult;
};

版本 2:

class foo2
{
public:
    foo2() : m_bNeedUpdate(false) {}

    void add_data(data n)
    {
        std::lock_guard<std::mutex> lock(m_mut);

        // ... restore new data to m_SomeData

        m_bNeedUpdate.store(true);
    }

    some_result get_result() const
    {
        if (m_bNeedUpdate.load())
        {
            std::lock_guard<std::mutex> lock(m_mut);
            if (m_bNeedUpdate.load())
            {
                // ... process mSomeData and update m_SomeResult

                m_bNeedUpdate.store(false);
            }
        }
        return m_SomeResult;
    }

private:
    mutable std::mutex          m_mut;
    mutable std::atomic<bool>   m_bNeedUpdate;
    some_data                   m_SomeData;

    mutable some_result         m_SomeResult;
};

最佳答案

问题是版本 2 不是线程安全的,至少 根据 C++11(和更早的 Posix);你正在访问 可以在没有访问权限的情况下修改的变量 保护。 (众所周知,双重检查锁定模式是 坏了,看 http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf .) 它可以通过以下方式在 C++11(或不可移植的更早版本)中工作 使用原子变量,但你所写的结果 未定义的行为。

关于c++ - 在这种情况下 'double checked locking pattern' 对 std::mutex 有用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22804739/

相关文章:

c++ - 找出数组中出现次数最少的数

c++ - 为什么我的 rand() 产生负数?

c++ - linux中的pthread_mutex_t是否可重入(如果一个线程试图获取它已经持有的锁,则请求成功)

c++ - 在 While 循环中嵌套 if 语句?

c++ - 消除 HTML 的最佳 C/C++ 库?

c++ - 我怎样才能让编译时 const 对象配置有可变长度的数据 block ?

c++ - 将类成员数组组合到单个数组时性能受到影响

C++ IrrKlang 声音错误 - CreateIrrKlangDevice() 导致 undefined reference (非常长的引用)

class - PyBind11多种类型的模板类

c++ - clang libc++ 错误 : overload resolution selected implicitly-deleted copy assignment operator