Linux线程(七)

文章目录

  • Linux线程(七)
    • 一、单例模式
    • 二、STL、智能指针和线程安全
    • 三、其他常见的锁

一、单例模式

  • 1.什么是单例模式?

单例模式是一种经典的“设计模式”,保证类在内存中只能有一个对象

  • 2.什么是设计模式?
  • 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。
  • 使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。
  • 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。
  • 项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。
  • 3.单例模式的特点:
  • 私有化的构造函数
  • 私有的静态的全局变量
  • 公有的静态的方法
  • 4.饿汉式和懒汉式的实现方法:
  • 饿汉式:类加载的时候就实例化,并且创建单例对象,简单来说,就是吃完饭立即洗完,下次就直接使用
template<class T>
class Singleton
{public:static T*  GetInstance(){return &data;}private:static T date;
};
  • 懒汉式:默认不会实例化,什么时候用什么时候new
  • 简单来说,懒汉式就是吃完饭不立即洗碗,而是什么时候用,什么时候洗。懒汉式的优点思想是“延时加载”,从而能够优化服务器的启动数度
template<class T>
class Singleton
{public:
static T* GetInstance()
{if(inst == NULL){inst == new T ();}return inst;
}private:static T* inst;};

这样写懒汉式的实现方法有一个严重的缺陷:线程不安全,第一次调用时如果有两个线程同时调用,可能会创建出两个T类型对象的实例,后面调用就不会出现问题了。

  • 懒汉式实现单例模式的线程安全版本
template<class T>
class Singleton
{public://双重判定空指针,降低锁冲突的概率,提高性能,使用互斥锁,保证多线程//下一次也只能new出一个对象实例static T* GetInstence(){if(inst == NULL)//第一重检查,检查inst是否已经指向某个对象实例,//注意此处在多线程的高并发情况下,可能会有多个//线程进入到第一个if里面{lock.lock();//加锁,保证在多线程的情况下一次也只能有一个线程进入if(inst == NULL)//第二重检查,检查inst是否为空//假设没有第二重检查,那么前面说过,进入第一个if//里面的线程可能有多个,此时第一个线程获得到锁后,//new出一个对象,释放锁,接着第二个线程或得到锁,//继续new出对象,这样就不满足单例模式的要求。{inst = new T();}lock.unlock();}return inst;}private://使用volatile关键字,防止被编译器优化volatile static T* inst;//这里使用volatile关键字的原因是://因为inst = new T();这条语句是非原子的,实际上会执行以下操作://a.在堆上开辟空间 b.初始化 c.把inst指向开辟的空间。//假设不加volatile关键字,那么正常的执行顺序是abc,那么被编译器//优化后的执行顺须就可能变为bca等,就达不到new的目的,所以voaltile//的目的是禁止编译器优化static std::mutex lock;
};

二、STL、智能指针和线程安全

  • 1.STL中的容器是否线程安全:

答案是:

  • 不是线程安全的。原因是:STL的设计初衷是将性能提升到极致,简单来说STL就是为了代码运行效率设计的,而一旦设计线程安全问题,会对代码的性能造成巨大影响
  • STL是在C++98就提出了,而线程安全是在C++11提出的
  • 2.智能指针是否线程安全?
  • 对于unique_ptr:由于只是在当前代码块的范围内生效,因此不涉及线程安全问题
  • 对于shared_ptr:多个对象需要需要共享一个引用计数变量,所以存在线程安全问题,但是标准库实现的时候考虑到这个问题,基于原子操作的(CAS)方式保证shared_ptr的能够高效,原子的操作引用计数

三、其他常见的锁

  • 悲观锁:在每次取数据时,总是担心数据会被其他线程修改,所以会在取数据前先加锁(读锁,写锁,行锁等),当其他线程想要访问数据时,被阻塞挂起
  • 乐观锁:每次取数据时候,总是乐观的认为数据不会被其他线程修改,因此不上锁。但是在更新数据前,会判断其他数据在更新前有没有对数据进行修改。主要采用两种方式:版本号机制和CAS操作

CAS操作:当需要更新数据时,判断当前内存值和之前取得的值是否相等。如果相等则用新值更新。若不等则失败,失败则重试,一般是一个自旋的过程,即不断重试

  • 自旋锁,公平锁,非公平锁

Linux线程(七)相关推荐

  1. Linux线程属性总结 http://blog.csdn.net/zsf8701/article/details/7842392

    Linux线程属性总结 分类: Linux 2012-08-08 11:05  3657人阅读  评论(2)  收藏  举报 linux thread solaris concurrency syst ...

  2. [转载]Linux 线程实现机制分析

    自从多线程编程的概念出现在 Linux 中以来,Linux 多线应用的发展总是与两个问题脱不开干系:兼容性.效率.本文从线程模型入手,通过分析目前 Linux 平台上最流行的 LinuxThreads ...

  3. Linux 线程的创建与同步

    Linux 线程的创建与同步 1.线程的定义 2.线程的创建和使用 3.理解线程的并发运行 3.线程同步 3.线程的实现 1.线程的定义 线程:进程内部的一条执行路径.是资源调度和执行的基本单位. 进 ...

  4. linux 线程操作问题undefined reference to ‘pthread_create‘的解决办法(cmake)

    linux 线程操作问题undefined reference to 'pthread_create'的解决办法(cmake) 参考文章: (1)linux 线程操作问题undefined refer ...

  5. linux线程的实现【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3620204.html 首先从OS设计原理上阐明三种线程:内核线程.轻量级进程.用户线程 内核线程 内核线程就是内核的分身,一个 ...

  6. linux 线程 进程经典文章

    进程是程 序在计算机上的一次执行活动.当你运行一个程序,你就启动了一个进程.显然,程序是 死的(静态的),进程是活的(动态的).进程可以分为系统进程和用户进程.凡是用于完成操作系统的各种功能的进程就是 ...

  7. linux 线程--内核线程、用户线程实现方法

    Linux上进程分3种,内核线程(或者叫核心进程).用户进程.用户线程 内核线程拥有 进程描述符.PID.进程正文段.核心堆栈 当和用户进程拥有相同的static_prio 时,内核线程有机会得到更多 ...

  8. Linux 线程与进程,以及通信

    http://blog.chinaunix.net/uid-25324849-id-3110075.html 部分转自:http://blog.chinaunix.net/uid-20620288-i ...

  9. Linux线程-互斥锁pthread_mutex_t

    Linux线程-互斥锁pthread_mutex_t 在线程实际运行过程中,我们经常需要多个线程保持同步.这时可以用互斥锁来完成任务:互斥锁的使用过程中,主要有pthread_mutex_init, ...

最新文章

  1. 教你用 buildroot 构建根文件系统
  2. KM(知识管理)与SharePoint Portal
  3. [转]python yield
  4. java内存回收机制
  5. org.springframework.uti包下的StringUtils的使用和org.apache.commons.lang包下StringUtils的使用
  6. java商城_基于Java,jfinal web框架开发出微信商城,微信分销商城源码分享
  7. 常用Flex IOC框架比较分析【转载】
  8. Tomcat8服务器在Cookie中添加当前系统时间报错
  9. 三维视觉基础之世界坐标系、相机坐标系、图像坐标系和像素坐标系之间的转换关系
  10. FHQ Treap摘要
  11. 【大数据部落】R语言犯罪率回归模型报告Regression model on crimerate report
  12. TableViewCell的折展(Masonry)
  13. Diffusion Models:生成扩散模型
  14. 偶滴神嘞~终于弹钢琴了
  15. 总结各种RGB转YUV的转换公式
  16. python汉字字体宋体_设置matplotlib中文显示(宋体)
  17. 如何用数学课件制作工具推导圆面积公式
  18. 蓝桥杯 18总决赛 A2 方阵阅兵(暴力)
  19. iOS中JPG PNG GIF格式图片的区分
  20. JAVA:基本运算符及应用:这是一个闰年吗?

热门文章

  1. 洛谷P4319 变化的道路
  2. 朴素贝叶斯法---朴素贝叶斯法的参数估计
  3. 用VIPER构建iOS应用
  4. 回到网易后开源APM技术选型与实战
  5. 在Elasticsearch中查询Term Vectors词条向量信息
  6. 交换算法经常使用的两个数的值
  7. 牛客多校10 - Identical Trees(dp+二分图最小权匹配)
  8. HDU多校6 - 6836 Expectation(矩阵树定理+高斯消元求行列式)
  9. CodeForces - 123B Squares(简单几何+旋转坐标系)
  10. CodeForces - 1287C Garland(贪心)