单例类的线程安全

文章讨论了在多线程环境中,如果单例类构造时间较长,可能导致线程安全问题,即多个线程创建了不同实例。为解决此问题,提出了使用互斥锁保护构造过程的传统方法以及C++11中利用局部静态特性的优雅解决方案。这两种方法都能确保单例类在多线程中的正确初始化和线程安全性。
摘要由CSDN通过智能技术生成

        在最近的开发项目中,发现如果单例类的构造时间较长(500±50 ms)的话,可能存在其他线程中调用GetInstance()接口时,main函数中的单例类对象初始化还未完成。这种情况下,单例类可能会创建两个。第一个单例类是创建好的,第二个会出现某些异常现象,例如:空指针,未获取到资源等...然后当第二个创建完毕之后,会覆盖掉类中的instance指针,导致后续的GetInstance()接口异常。由于构造时间较长所以多线程中同时申请对象时发生两次甚至多次构造的几率增加。

为了避免这类情况发生,需要考虑多线程中单例类构造过程中的线程安全。

所谓的单例类,不过是C++应用层面抽象出来的一种类的实现方式。

在多线程中实现单例类时,可能导致多个线程申请了不同的类实例,从而指向了不同的内存空间。

因为用户在设计这个单例类的时候并没有考虑多线程申请类实例的情况,仅仅时实现了一个最基础的单例类。

在使用C++单例类设计模式的时候,用户需要评估是否存在多线程申请类实例的使用场景,若存在,需要在申请实例的函数内使用锁机制对申请过程进行保护,这样才能保证线程安全。

    private:
        static std::mutex mutex_;
    
    public:
        static Creat * GetInstance() {
            std::lock_guard<std::mutex> lock(mutex_);

            ...


std::mutex Creat::mutex_;     //别忘记类外分配内存

上述加互斥锁的写法已经过时了,下面是C++11优雅写法:

class SingleCreat {

public:

    static SingleCreat &GetInstance(); /* 局部静态特性的方式实现单实例 */
	
private:

    SingleCreat(); /* 禁止外部构造 */

    ~SingleCreat(); /* 禁止外部析构 */

    SingleCreat(const SingleCreat &signal); /* 禁止外部复制构造 */

    SingleCreat&operator=(const SingleCreat &signal); /* 禁止外部赋值操作 */
};

SingleCreat &SingleCreat::GetInstance() {
    static SingleCreat signal;
    return signal;
}


SingleCreat::SingleCreat() {
}

SingleCreat::~SingleCreat() {
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值