muduo网络库:05---线程同步精要之(线程安全的Singleton实现)

一、DCL

  • 研究Singleton的线程安全实现的历史会发现很多有意思的事情,人们一度认为double checked locking(缩写为DCL)是王道,兼顾了效率与正确性。后来有“神牛”指出由于乱序执行的影响,DCL是靠不住的。可以参阅:
  • Java开发者还算幸运,可以借助内部静态类的装载来实现。C++就比较惨,要么次次锁,要么eager initialize,或者动用memory barrier这样的“大杀器”
  • Java 5修订了内存模型,并给volatile赋予了acquire/release语义,这下DCL(with volatile)又是安全的了。然而C++的内存模型还在修订中(C++11已经有了全新定义的内存模式,可参阅:http://scottmeyers.blogspot.com/2012/04/information-on-c11-memory-model.html),C++的volatile目前还不能(将来也难说)保证DCL的正确性(只在Visual C++ 2005及以上版本有效)

二、pthread_once

  • 其实没有那么麻烦,在实践中用pthread_once就行:
template<typename T>
class Singleton :boost::noncopyable {
private:
    static T& instance()
    {
        pthread_once(&ponce_, &Signleton::init);
        return *value_;
    }
private:
    Singleton();
    ~Singleton();

    static void init()
    {
        value_ = new T();
    }
private:
    static pthread_oncet ponce_;
    static T* value_;
};

//必须在头文件中定义static变量
template<typename T>
pthread_oncet Singleton<T>::ponce_ = PTHREAD_ONCE_INIT;

template<typename T>
T* Singleton<T>::value_ = NULL;
  • 上面这个Singleton没有任何花哨的技巧:
    • 它用pthread_once_t来保证 lazy-initialization的线程安全
    • 线程安全性由Pthreads库保证,如果系统的Pthreads库有bug,那就认命吧,多线程程序反正也不可能正确执行了
  • 使用方法也很简单:
Foo& foo = Singleton<Foo>::instance();
  • 这个Singleton没有考虑对象的销毁:
    • 在长时间运行的服务器程序里,这不是一个问题,反正进程也不打算正常退出(参阅后面的“分布式系统工程实践之能随时重启进行作为系统的重要目标”)
    • 在短期运行的程序中,程序退出的时候自然就释放所有资源了(前提是程序里不使用不能由操作系统自动关闭的资源,比如跨进程的mutex)
    • 在实际的muduo::Singleton class中,通过atexit提供了销毁功能,聊胜于无罢了
  • 另外,这个Singleton只能调用默认构造函数,如果用户想要指定T的构造方式,我们可以用模板特化技术来提供 一个定制点,这需要引入另一层间接

三、附加

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董哥的黑板报

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值