• 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
  • 相关阅读:
    chromium的下载和编译(流程详解)
    互联网公司都怎么实现分页的,拿 MySQL 使劲Limit?
    Sulley入门教学——简介、安装(Win7、VMware)
    C++默认参数(实参)
    django路由匹配、反向解析、无名有名反向解析、路由分发、名称空间
    Linux驱动开发——USB设备驱动
    适合能源企业的文档安全外发系统应该是什么样的?
    nginx-根据X-Forwarded-For设置访问黑白名单
    HttpClient MultipartEntityBuilder中文乱码问题解决
    Python 博客园备份迁移脚本
  • 原文地址:https://blog.csdn.net/www_dong/article/details/126294744