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

std::system Exception when instantiating a singleton object

本文关键字:异常 对象 单一 system 实例化 std 实例      更新时间:2023-10-16

我正在学习如何在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;
}

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

terminate called after throwing an instance of 'std::system_error'
what():  Unknown error -1
Aborted

我尝试用gdb调试程序。调用std::call_once时似乎会抛出异常。我不确定发生了什么,但我假设 lambda 表达式无法创建对象。

第二个问题。有没有办法知道未知错误代码的实际含义?我认为在尝试确定问题时,-1不会有太大帮助。

感谢您的帮助。

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

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

Singleton& Singleton::get_instance(){
    static Singleton instance;
    return instance;
}

这是线程安全的,并且将导致instance变量仅初始化一次。 这篇维基百科文章很好地解释了它在引擎盖下如何 https://en.wikipedia.org/wiki/Double-checked_locking 工作。 最好让编译器尽可能为您安排代码。 同样如评论中所述,这个问题也有关于上述的有用信息 迈耶斯对单例模式线程的实现是否安全?