将问题与std :: mutex和std :: atomic联系起来

时间:2014-11-28 16:21:51

标签: c++ multithreading c++11 visual-studio-2013 stdatomic

我有这个:

Singleton.h

#ifndef SINGLETON_H
#define SINGLETON_H

#include <atomic>
#include <mutex>

class Singleton
{
public:
    static std::atomic<Singleton*> Singleton::m_instance;
    static std::mutex Singleton::m_mutex;
    static Singleton* getInstance();

    Singleton();
    ~Singleton();
};

#endif

Singleton.cpp

#include "Singleton.h"

Singleton::Singleton()
{
}

Singleton* Singleton::getInstance() 
{
    Singleton* tmp = m_instance.load(std::memory_order_relaxed);
    std::atomic_thread_fence(std::memory_order_acquire);
    if (tmp == nullptr) 
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        tmp = m_instance.load(std::memory_order_relaxed);
        if (tmp == nullptr) 
        {
            tmp = new Singleton;
            std::atomic_thread_fence(std::memory_order_release);
            m_instance.store(tmp, std::memory_order_relaxed);
        }
    }
    return tmp;
}

Singleton::~Singleton() {}

的main.cpp

#include "Singleton.h"
#include <iostream>
int main()
{
    Singleton* singleton = Singleton::getInstance();
    std::cout << "Hello World!" << std::endl;
    return 0;
}

当我尝试构建时,我得到了这个错误(Visual studio):

  

错误1错误LNK2001:未解析的外部符号&#34; public:static   struct std :: atomic Singleton :: m_instance&#34;   (?m_instance @辛格尔顿@@ 2U?$ @原子@@@ PAVSingleton STD @@ A)   c:...... Singleton.obj Singleton

  

错误2错误LNK2001:未解析的外部符号&#34; public:static   class std :: mutex Singleton :: m_mutex&#34;   (?m_mutex @ Singleton @@ 2Vmutex @ std @@ A)c:\ Users \ InusualZ \ documents \ visual   ...... Singleton.obj Singleton

1 个答案:

答案 0 :(得分:3)

您需要在源文件中定义静态成员变量,而不只是在类定义中声明它们:

std::atomic<Singleton*> Singleton::m_instance;
std::mutex Singleton::m_mutex;

您可能有兴趣知道使用简单的本地静态变量可以实现几乎完全相同的延迟线程安全初始化:

Singleton* Singleton::getInstance() {
    static Singleton instance;
    return &instance;
}

这可以修复内存泄漏,但如果您尝试从另一个静态变量的析构函数访问它,则会引入潜在的deathtrap。在没有某些问题的情况下,无法在C ++中实现Singleton反模式。你应该think again关于单身是否适合你的设计。根据我的经验,它永远不会。