相关疑难解决方法(0)

C++ 11中的Double-Checked Lock Singleton

以下单例实现数据 - 竞争是免费的吗?

static std::atomic<Tp *> m_instance;
...

static Tp &
instance()
{
    if (!m_instance.load(std::memory_order_relaxed))
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        if (!m_instance.load(std::memory_order_acquire))
        {
            Tp * i = new Tp;
            m_instance.store(i, std::memory_order_release);    
        }    
    }

    return * m_instance.load(std::memory_order_relaxed);
}
Run Code Online (Sandbox Code Playgroud)

是std::memory_model_acquire了负载运行的多余?是否可以通过将它们切换到进一步放宽加载和存储操作std::memory_order_relaxed?在这种情况下,获取/释放语义是否std::mutex足以保证其正确性,或者std::atomic_thread_fence(std::memory_order_release)还需要确保构造函数的内存写入在轻松存储之前发生?然而,使用栅栏相当于有商店memory_order_release吗?

编辑:感谢John的回答,我提出了以下应该是数据竞争的实现.尽管内部负载可能完全是非原子的,但我决定放弃一个宽松的负载,因为它不会影响性能.与总是具有获取存储器顺序的外部负载相比,thread_local机器提高了访问大约一个数量级的实例的性能.

static Tp &
instance()
{
    static thread_local Tp *instance;

    if (!instance && 
        !(instance = m_instance.load(std::memory_order_acquire)))
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        if (!(instance = m_instance.load(std::memory_order_relaxed)))
        {
            instance = new Tp; 
            m_instance.store(instance, std::memory_order_release);    
        }    
    }
    return …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading atomic c++11

43
推荐指数
3
解决办法
1万
查看次数

标签 统计

atomic ×1

c++ ×1

c++11 ×1

multithreading ×1