基于线程安全的单例模式

今天被问到单例模式了,之前没有很关注线程安全问题,结果悲剧了。这里主要有两个问题:

1) 加锁

2) 要粒度细,也就是说尽量锁最少的代码


所以我们必须加锁,而且只要锁住new就可以了,不要在if判断之前锁。但是这里有出现一个问题就是,如果我们仅仅锁住new的话,伪代码如下

testobj * getinstance()

{

  if(m_instance ==NULL)

  {

    lock

    m_instance =  new testobj();

    unlock

  }

}


那么假如有两个线程(A和B)同时调用getinstance,两个都通过了if的判断,从而开始竞争锁,比如A先得到锁资源,那么m_instance 会被new出来,然后释放锁,接着B得到锁,接着又去new了一把,其实这个时候m_instance已经存在了,不用new了。所以我们要用double check


另外对m_instance的初始化时单例模式很重要的一个部分


#include <stdio.h>

#include <pthread.h>

class CLocks{
private:
  pthread_mutex_t m_mutex;
public:
  CLocks()
  {
    pthread_mutex_init(&m_mutex,NULL);
  }
  
  ~CLocks(){
    pthread_mutex_destroy(&m_mutex);
  }
  


  void Lock(){ pthread_mutex_lock(&m_mutex);}
  void UnLock() { pthread_mutex_unlock(&m_mutex); }
};


class A{
private:
  static A * m_instance;
  A(){}
  A(A&){}
  A& operator=(const A&);
  static CLocks m_lock;
public:
  static A* getinstance()
  {
    if(m_instance == NULL)
{
 m_lock.Lock();
 //两次m_instance的判断为,double check,防止被new多次
 if(m_instance == NULL)
 {
   m_instance = new A();
 }
 m_lock.UnLock();
}

return m_instance;
  }
};


//初始化很重要的啊
CLocks A::m_lock;
A* A::m_instance = NULL;


int main( ) 

A * pa = A::getinstance();


return 0; 

}


C++完美实现Singleton模式 http://www.cppblog.com/dyj057/archive/2005/09/20/346.aspx 写得很好的一篇文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值