muduo网络库学习笔记(6):单例类(线程安全的)
来源:互联网 发布:大数据前沿技术应用 编辑:程序博客网 时间:2024/05/18 19:39
muduo用pthread_once实现了线程安全的Singleton。
文件名:Singleton.htemplate<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(); } static pthread_once_t ponce_; static T* value_;};template<typename T>pthread_once_t Singleton::ponce_ = PTHREAD_ONCE_INIT;template<typename T>T* Singleton<T>::value_ = NULL;
使用方法也很简单:
Foo& foo = Singleton<Foo>::instance();
其中有哪些知识点呢?
(1)了解单例模式
实际应用中,有些对象,我们只需要一个就可以了,比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个,这里就可以通过单例模式来避免两个打印作业同时输出到打印机中,即在整个的打印过程中只有一个打印程序的实例。
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。
(2)pthread_once
#include <pthread.h>int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));pthread_once_t once_control = PTHREAD_ONCE_INIT;
本函数使用初值为PTHREAD_ONCE_INIT的once_control变量保证init_routine()函数在本进程执行序列中仅执行一次,且能保证线程安全。(我们还能用互斥锁的方式来实现线程安全,但效率没有pthread_once高)
(3)atexit
// atexit()函数用来注册程序正常终止时要被调用的函数// 在一个程序中最多可以用atexit()注册32个处理函数// 这些处理函数的调用顺序与其注册的顺序相反// 即最先注册的最后调用,最后注册的最先调用#include<stdlib.h>int atexit(void (*func)(void)); // 登记的函数类型为不接受任何参数的void函数
在Singleton.h中,atexit函数被用于注册一个销毁函数,在程序结束的时候会自动调用销毁函数,就不用手动调用了。
(4)typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
在C++中,类型有Complete type和Incomplete type之分,对于Complete type, 它的大小在编译时是可以确定的,而对于Incomplete type, 它的大小在编译时是不能确定的。
用delete删除一个只有声明但无定义的类型的指针(即不完整类型),是危险的。这通常导致无法调用析构函数(包括对象本身的析构函数、成员/基类的析构函数),从而泄露资源。
而通过 typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1]; 这种做法能使当T为不完整类型时编译报错。(当T为不完整类型时,sizeof(T)给出的是0,根据代码规则,-1是不能作为数组的size的,因此,这里相当于强制编译器给出error而不是 warning)
- muduo网络库学习笔记(6):单例类(线程安全的)
- muduo网络库学习笔记(5):线程池的实现
- muduo网络库学习笔记(7):线程特定数据
- muduo网络库源码学习————线程安全
- muduo网络库学习笔记(10):定时器的实现
- muduo网络库源码学习————线程本地单例类封装
- muduo网络库学习笔记(1):Timestamp类
- muduo网络库学习笔记(2):原子性操作
- muduo网络库学习笔记(3):Thread类
- muduo网络库学习笔记(4):互斥量和条件变量
- muduo网络库学习笔记(12):TcpServer和TcpConnection类
- muduo网络库学习笔记(8):高效日志类的封装
- muduo网络库学习笔记(9):Reactor模式的关键结构
- muduo网络库学习笔记(11):有用的EventLoop::runInLoop()函数
- muduo网络库学习笔记(13):TcpConnection生命期的管理
- muduo网络库学习笔记(15):关于使用stdio和iostream的讨论
- muduo网络库学习之muduo_http 库涉及到的类
- muduo网络库学习之muduo_inspect 库涉及到的类
- 最后一公里极速配送(一)
- jQuery插件开发精品教程(让你的jQuery更上一个台阶)
- The latest results from the Alpha Magnetic Spectrometer on the International Space Station
- VC++ 动态链接库编程
- 几分钟时间,搞清开源许可证之间的区别
- muduo网络库学习笔记(6):单例类(线程安全的)
- 代理详解 传值
- android中Root权限的判断与获取
- Leetcode no. 14
- Mysql和Oracle数据库sql执行过程的区别
- Linux Centos 6.5 安装FFMPEG && 故障排查
- Linux kernel 的 sendfile 是如何提高性能的
- IP地址0.0.0.0是什么意思?
- 上一周的知识点总结以及思路的理解