C++多线程的Singleton(2)

C++多线程的Singleton(1)

 

如果你的系统有读写锁,恭喜你,也许你可以比较方便的解决这个问题。你可以这么写:

// Singleton.h
class Singleton
{
  public:
     ~Singleton(){}
     static Singleton& getInstance();

  private:
     Singleton(){}
     static RWLock rwlock_;
};

// Singleton.cpp

/* static */
Lock Singleton::lock_;

Singleton& Singleton::getInstance()
{
  static Singleton *instance = NULL;
  rwlock.rdlock(); 
  if (NULL == instance) // thread B Pos1
  {
    rwlock.unlock();
    {
      WLockGuard wguard(rwlock);
  if (NULL == instance) 
      {
          instance = new Singleton;  // thread A   Pos2
       }
       return instance;
    }
  }
  rwlock.unlock();
  return &instance;
} 

 这段代码没有符合一个return的原则,之所以这么写是因为singleton的构造函数有可能会有异常,那么这么封装,可以最大程度的保证不会死锁。这段代码比上一段已经有很大程度的改变了。首先,当instance初始化之后,以后就全部是读锁了,只有一个简单函数的开销(相对被mutex锁住切换context的开销,一个函数的调用要小多了,这个函数不是指rwlock.rdlock(),因为这个函数本身100%是inline的;而是指pthread_rwlock_rdlock这样的函数调用)。但是大家也许已经发现了,如果在很多线程同时初始化这个instance的时候,还是会有等待锁的情况发生。那有没有办法解决这个问题呢?答案是可以的,不过需要用到一些同步原语,包括Atomic和Memory Barrier。我不会再写去了,因为我觉得这些高级的功能,我们一定要抵制这种诱惑。因为如果用这些你的代码会有以下两个缺点:

(1)可读性较差

(2)移植性较差(你可以写很多宏来帮助你在不同平台不同CPU上使用,譬如Chrome)

如果你有兴趣,请察看chrome的源代码的Base/singleton的实现。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值