C++ linux线程安全单例Singleton
2016-07-03 16:15
615 查看
DCL(double checked locking)
//class singleton
//:s1-
singleton* get_instance(void)
{
lock();
if( instance == 0) {
instance = new singleton;
}
unlock();
return instance;
}
**存在的问题是:无论是否已经初始化都要加锁,增加了负荷,已经没有所谓的并发性能了。
//:s-2
**存在的问题是:不能保证临界区只初始化一次,没能实现singleton的基本功能;
//:s-3
**解决路上述问题——双检锁模式,兼顾了效率和正确性。还来有人指出由于乱序执行的影响,DCL是靠不住的。
可以借助其他语言的一些机制,如eager initialization,memory barrier。
不过,如果支持pthread的话,可以站在巨人的肩膀,pthread_once
int pthread_once(pthread_once_t *once_control, void (*init_routine) (void));
功能:本函数使用初值为PTHREAD_ONCE_INIT的once_control变量保证init_routine()函数在本进程执行序列中仅执行一次。
在多线程编程环境下,尽管pthread_once()调用会出现在多个线程中,init_routine()函数仅执行一次,究竟在哪个线程中执行是不定的,是由内核调度来决定。
线程安全性由Pthreads库保证。
注意这里没有考虑对象销毁
//class singleton
//:s1-
singleton* get_instance(void)
{
lock();
if( instance == 0) {
instance = new singleton;
}
unlock();
return instance;
}
**存在的问题是:无论是否已经初始化都要加锁,增加了负荷,已经没有所谓的并发性能了。
//:s-2
singleton* get_instance(void) { if( instance == 0){ lock(); instance = new singleton; unlock(); } return instance; }
**存在的问题是:不能保证临界区只初始化一次,没能实现singleton的基本功能;
//:s-3
singleton* get_instance(void) { if( instance == 0){ lock(); if( instance == 0 ) instance = new singleton; unlock(); } return instance; }
**解决路上述问题——双检锁模式,兼顾了效率和正确性。还来有人指出由于乱序执行的影响,DCL是靠不住的。
可以借助其他语言的一些机制,如eager initialization,memory barrier。
不过,如果支持pthread的话,可以站在巨人的肩膀,pthread_once
int pthread_once(pthread_once_t *once_control, void (*init_routine) (void));
功能:本函数使用初值为PTHREAD_ONCE_INIT的once_control变量保证init_routine()函数在本进程执行序列中仅执行一次。
在多线程编程环境下,尽管pthread_once()调用会出现在多个线程中,init_routine()函数仅执行一次,究竟在哪个线程中执行是不定的,是由内核调度来决定。
线程安全性由Pthreads库保证。
template<typename T> class Singleton:boost::noncopyable { public: static T& instance() { pthread_once(&ponce_, &Singleton::init); return *value_; } private: Singleton(); ~Singleton(); static void init() { value_ = new T(); } private: static pthread_once_t ponce_; static T* value_; } //必须在头文件中定义static 变量 template<typename T> pthread_once_t Singleton<T>::ponce_ = PTHREAD_ONCE_INIT; template<typename T> T* Singleton<T>::value_ = NULL;
注意这里没有考虑对象销毁
相关文章推荐
- 内核模块学习之简单的内核模块编写
- linux 软件管理
- linux下线程的分离状态和结合状态
- 每天一个linux命令(33)--df命令
- linux下安装svn,lnmp
- 进程间通信方式
- Linux用户和组管理
- linux-OVF模板部署问题
- linux 查看内核版本或系统版本
- linux-centos6.5一键安装 禅道
- Linux下的进程通信方式(IPC)——管道通信
- linux-centos6.5一键安装 Redmine
- rabbitmq集群搭建(centos6.5)
- 【转载】VMware NAT端口映射外网访问虚拟机linux
- SVN迁移--windows7迁移到centos6.5
- linux 安装/卸载boost
- Linux下视频转换工具:转换,切割,连接,
- Linux下视频转换工具:转换,切割,连接,
- Linux之Vim(三):Vim插件使用导航
- 2.1 Linux进程介绍