• c++——线程安全的单例


    方式1—静态局部变量实现单例

    线程安全,c++11之后支持。实现代码如下:

    class Singleton
    {
    public:
        static Singleton *getInstance()
        {
            static Singleton instance;
            return &instance;
        }
    private:
        Singleton() {}
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    局部静态变量的初始化时机:

    • 发生在函数第一次被调用到局部静态变量定义语句时;

    静态局部变量的特点:

    • 在全局数据区分配内存;
    • 静态局部变量一般在声明时初始化,如果没有被显式初始化,会被程序自动初始化为0;

    在c++98/03标准中,不是线程安全的,实际实现代码如下:

    static Singleton& getInstance()
    {
        static bool initialized = false;
        static char buf[sizeof(Singleton)];
    
        if (!initialized) {
            initialized = true;
            new(&buf) Singleton();
        }
    
        return (*(reinterpret_cast( &buf)));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    c++11后做了改进,保证了线程安全,大概描述如下:

    such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization. If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.
    
    • 1

    主要实现方式:

    • 在当前线程执行到需要初始化变量的地方时,如果有其他线程正在初始化该变量,则阻塞当前线程,直到初始化完成为止。

    方式2—std::call_once

    线程安全,c++11之后支持。实现代码如下:

    class Singleton
    {
    public:
       static Singleton& getInstance()
       {
           static std::once_flag s_flag;
           std::call_once(s_flag,[&](){
            m_instance.reset(new Singleton());
           });
           return *m_instance;
       }
        
       ~ Singleton() = default;
        
    private:
       Singleton() = default;
       Singleton& operator=(const Singleton&) = delete;
       Singleton(const Singleton&) = delete;
        
    private:
       static std::unique_ptr m_instance;
    }
    
    std::unique_ptr Singleton::m_instance;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    RPA在跨境电商领域在哪些应用场景?
    Html-定位(Position)
    怎么使用LightPicture开源搭建图片管理系统并远程访问?【搭建私人图床】
    LeetCode 55. 跳跃游戏
    mongo加入systemctl进行管理服务
    Docker中安装mysql
    第二十四章 源代码文件 REST API 参考(六)
    Canal
    uniCloud 如何创建数据表
    Python 大麦抢票脚本
  • 原文地址:https://blog.csdn.net/www_dong/article/details/126294744