线程安全使用单例模式,保证了每次只创建单个对象,代码如下:

Singleton.h

  1. // Use of this source code is governed by a BSD-style license
  2. // that can be found in the License file.
  3. //
  4. // Author: Shuo Chen (chenshuo at chenshuo dot com)
  5. //线程安全
  6. #ifndef MUDUO_BASE_SINGLETON_H
  7. #define MUDUO_BASE_SINGLETON_H
  8. //单例
  9. #include <boost/noncopyable.hpp>
  10. #include <pthread.h>
  11. #include <stdlib.h> // atexit
  12. namespace muduo
  13. {
  14. template<typename T>
  15. class Singleton : boost::noncopyable//继承自noncopyable表示不可被拷贝
  16. {
  17. public:
  18. static T& instance()//返回该类单例对象
  19. {
  20. pthread_once(&ponce_, &Singleton::init);//ponce_能够保证该函数只被执行一次,而且能够保证线程安全
  21. return *value_;
  22. }
  23. private:
  24. Singleton();//构造函数
  25. ~Singleton();//析构函数
  26. static void init()//在内部创建的对象
  27. {
  28. value_ = new T();
  29. ::atexit(destroy);//在程序结束的时候会自动调用destroy
  30. }
  31. static void destroy()//在内部销毁的对象
  32. {//这句保证了T是一个完全类型的类,否则该数组的大小为-1,编译时会产生警告
  33. typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
  34. delete value_;
  35. }
  36. private:
  37. static pthread_once_t ponce_;//这个对象能够保证一个函数只被执行一次
  38. static T* value_;
  39. };
  40. template<typename T>
  41. pthread_once_t Singleton<T>::ponce_ = PTHREAD_ONCE_INIT;
  42. template<typename T>
  43. T* Singleton<T>::value_ = NULL;
  44. }
  45. #endif

测试代码如下,该代码在主线程中创建一个单例对象,然后在子线程中改变该对象的名称,由于是单例对象,最后主线程打印的时候名称也是改变了的

  1. //线程安全测试程序
  2. #include <muduo/base/Singleton.h>
  3. #include <muduo/base/CurrentThread.h>
  4. #include <muduo/base/Thread.h>
  5. #include <boost/noncopyable.hpp>
  6. #include <stdio.h>
  7. //定义Test类
  8. class Test : boost::noncopyable
  9. {
  10. public:
  11. Test()
  12. {//%p是指针的值
  13. printf("tid=%d, constructing %p\n", muduo::CurrentThread::tid(), this);
  14. }
  15. ~Test()
  16. {
  17. printf("tid=%d, destructing %p %s\n", muduo::CurrentThread::tid(), this, name_.c_str());
  18. }
  19. const muduo::string& name() const { return name_; }
  20. void setName(const muduo::string& n) { name_ = n; }//设置名称
  21. private:
  22. muduo::string name_;//名称
  23. };

单独编译后运行结构如下:

muduo网络库源码学习————线程安全的更多相关文章

  1. muduo网络库源码学习————线程池实现

    muduo库里面的线程池是固定线程池,即创建的线程池里面的线程个数是一定的,不是动态的.线程池里面一般要包含线程队列还有任务队列,外部程序将任务存放到线程池的任务队列中,线程池中的线程队列执行任务,也 ...

  2. muduo网络库源码学习————线程类

    muduo库里面的线程类是使用基于对象的编程思想,源码目录为muduo/base,如下所示: 线程类头文件: // Use of this source code is governed by a B ...

  3. muduo网络库源码学习————线程特定数据

    muduo库线程特定数据源码文件为ThreadLocal.h //线程本地存储 // Use of this source code is governed by a BSD-style licens ...

  4. muduo网络库源码学习————线程本地单例类封装

    muduo库中线程本地单例类封装代码是ThreadLocalSingleton.h 如下所示: //线程本地单例类封装 // Use of this source code is governed b ...

  5. muduo网络库源码学习————Timestamp.cc

    今天开始学习陈硕先生的muduo网络库,moduo网络库得到很多好评,陈硕先生自己也说核心代码不超过5000行,所以我觉得有必要拿过来好好学习下,学习的时候在源码上面添加一些自己的注释,方便日后理解, ...

  6. muduo网络库源码学习————互斥锁

    muduo源码的互斥锁源码位于muduo/base,Mutex.h,进行了两个类的封装,在实际的使用中更常使用MutexLockGuard类,因为该类可以在析构函数中自动解锁,避免了某些情况忘记解锁. ...

  7. muduo网络库源码学习————日志滚动

    muduo库里面的实现日志滚动有两种条件,一种是日志文件大小达到预设值,另一种是时间到达超过当天.滚动日志类的文件是LogFile.cc ,LogFile.h 代码如下: LogFile.cc #in ...

  8. muduo网络库源码学习————日志类封装

    muduo库里面的日志使方法如下 这里定义了一个宏 #define LOG_INFO if (muduo::Logger::logLevel() <= muduo::Logger::INFO) ...

  9. muduo网络库源码学习————无界队列和有界队列

    muduo库里实现了两个队列模板类:无界队列为BlockingQueue.h,有界队列为BoundedBlockingQueue.h,两个测试程序实现了生产者和消费者模型.(这里以无界队列为例,有界队 ...

随机推荐

  1. linux中的隐藏权限,chattr,lsattr

    chattr chattr可以用来制约root的权限,使得系统更加安全. 主要参数: a:让文件或目录仅供附加用途. b:不更新文件或目录的最后存取时间. c:将文件或目录压缩后存放. d:将文件或目 ...

  2. LInux文件管理篇,权限管理

    一: chgrp 改变文件所属用户组 chown 改变文件所有者 注意: 1.使用格式 chgrp/chown     user      file eg: chgrp lanyue permissi ...

  3. Erlang语言之简述及安装

    1. 简述 Erlang在1991年由爱立信公司向用户推出了第一个版本,经过不断的改进完善和发展,在1996年爱立信又为所有的Erlang用户提供了一个非常实用且稳定的OTP软件库并在1998年发布了 ...

  4. 数据表记录包含表索引和数值(int范围的整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出

    此题如果直接使用有序的TreeMap就不需要这样折腾: 1.map的key值唯一性,故就不在需要set集合来去重 2.使用map后利用key的唯一性,把序列号相同的数据直接加在一起,代码会很简洁 pa ...

  5. 在IDEA中搭建Java源码学习环境并上传到GitHub上

    打开IDEA新建一个项目 创建一个最简单的Java项目即可 在项目命名填写该项目的名称,我这里写的项目名为Java_Source_Study 点击Finished,然后在项目的src目录下新建源码文件 ...

  6. Python - 翻译Talk Python To Me (和我聊Python) 播客

    “和我聊Python”是一个美国的聊天播客,英文名Talk Python To Me,类似于喜马拉雅的音频课程节目,只不过这个主题是编程语言Python.该节目从2015年的节目到现在,已经超过256 ...

  7. 前端学习笔记-H5

    H5常用标签及其属性: <a>标签做超链接: <p>段落标签,自带段间距和换行样式: <div>块标签,表示一块内容,没有具体语意,区别与p标签,块与块间没有间距: ...

  8. selemiun 问题总结

    1.如果打开一个网页定位一个元素时发现不能够定位某一个元素,并且定位的方法没问题,则需要看下该网页是否有frame框架 解决办法: 如果有frame框架则需要先切换到frame框架下: driver. ...

  9. 看完肯定懂的 Java 字符串常量池指南

    字符串问题可谓是 Java 中经久不衰的问题,尤其是字符串常量池经常作为面试题出现.可即便是看似简单而又经常被提起的问题,还是有好多同学一知半解,看上去懂了,仔细分析起来却又发现不太明白. 背景说明 ...

  10. PHP pcntl

    来源:https://www.jianshu.com/p/de0b74f58f50 pcntl是一个可以利用操作系统的fork系统调用在PHP中实现多线程的进程控制扩展,当使用fork系统调用后执行的 ...