std :: system实例化单例对象时的异常

han*_*bal 2 c++ singleton c++11

我正在学习如何在以后实现线程安全的单例模式c++11.

#include <iostream>
#include <memory>
#include <mutex>

class Singleton
{
public:
    static Singleton& get_instance();
    void print();

private:
    static std::unique_ptr<Singleton> m_instance;
    static std::once_flag m_onceFlag;
    Singleton(){};
    Singleton(const Singleton& src);
    Singleton& operator=(const Singleton& rhs);
};

std::unique_ptr<Singleton> Singleton::m_instance = nullptr;
std::once_flag Singleton::m_onceFlag;

Singleton& Singleton::get_instance(){
        std::call_once(m_onceFlag, [](){m_instance.reset(new Singleton());});
        return *m_instance.get();
};

void Singleton::print(){
    std::cout << "Something" << std::endl;
}

int main(int argc, char const *argv[])
{
    Singleton::get_instance().print();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

代码编译很好,但在执行时我收到以下异常.

terminate called after throwing an instance of 'std::system_error'
what():  Unknown error -1
Aborted
Run Code Online (Sandbox Code Playgroud)

我试着调试程序gdb.似乎在调用时抛出了异常std::call_once.我不确定发生了什么,但我认为lambda表达式无法创建对象.

第二个问题.有没有办法知道未知错误代码究竟是什么意思?我认为-1在试图找出问题时,这样做无济于事.

谢谢你的帮助.

Cur*_*ous 5

发生这种情况是因为您没有使用该-pthread标志进行编译,并且正在尝试使用系统上本机线程库中的实用程序.

作为替代方案,请查看以下对单例模式定义的更改,在您的示例中称为"Meyers Singleton"

Singleton& Singleton::get_instance(){
    static Singleton instance;
    return instance;
}
Run Code Online (Sandbox Code Playgroud)

这是线程安全的,并且会导致instance变量只被初始化一次.这篇维基百科文章很好地解释了它如何在引擎盖下运行https://en.wikipedia.org/wiki/Double-checked_locking.尽可能让编译器为您安排代码. 同样如评论中所述,这个问题也有关于上述Is Meyers实现Singleton模式线程安全的有用信息吗?