当前位置: 首页 > news >正文

Linux--线程安全的单例模式--自旋锁--0211

1. 线程安全的单例模式

1.1 什么是单例模式

某些类, 只应该具有一个对象(实例), 就称之为单例.

1.1.1 懒汉方式实现单例模式

以上篇博文的线程池为例

Liunx--线程池的实现--0208 09_Gosolo!的博客-CSDN博客

  • 实现懒汉模式首先要先将构造函数私有化,并禁止生成默认的拷贝构造函数,赋值运算符重载,不能随意的构造出来对象。
  • 其次增加一个静态的线程池对象,才符合单例的条件。
  • 然后需要有一个函数可以用来构造对象,由于该函数需要知道静态线程池对象是否不为空,也就是需要访问静态成员,所以该函数也必须是静态的
template<class T>
class ThreadPool
{//...
private:ThreadPool(int thread_num=g_thread_num):num_(thread_num){//创造线程的空间 构造线程for(int i=1;i<=num_;i++){//每个线程的编号 回调函数 输出型参数threads_.push_back(new Thread(i,routine,this)); }pthread_mutex_init(&lock,nullptr);pthread_cond_init(&cond,nullptr);}ThreadPool(const ThreadPool<T>& other)=delete;const ThreadPool<T> operator=(const ThreadPool<T>& other)=delete;//...
public:static ThreadPool<T>* getThreadPool(int num=g_thread_num){if(nullptr==thread_ptr){thread_ptr=new ThreadPool<T>(num);}return thread_ptr;}
private:std::vector<Thread*> threads_;int num_;std::queue<T> task_queue_;pthread_mutex_t lock;//保护临界区(任务队列)的一把锁pthread_cond_t cond;static ThreadPool<T>* thread_ptr;//静态成员 在类外初始化
};
template<class T>
ThreadPool<T>* ThreadPool<T>::thread_ptr =nullptr;

 问题:

由于我们这个项目是线程池,有没有可能多个线程同时访问getThreadPool函数,都进入到了thread_ptr与nullptr这一步判断?

会的,这里是线程不安全的,我们需要加锁以保证安全。

1.1.2 懒汉方式实现线程安全的单例模式

在静态成员函数中加锁,所以该锁也需要是静态的成员变量。

template<class T>
class ThreadPool
{//...
private:ThreadPool(){}
public:static ThreadPool<T>* getThreadPool(int num=g_thread_num){if(nullptr==thread_ptr){//lockGuard lockguard(&mutex); 锁的封装 详细见上篇博文pthread_mutex_lock(&mutex);if(nullptr==thread_ptr){thread_ptr=new ThreadPool<T>(num);}pthread_mutex_unlock(&mutex);}return thread_ptr;}
private:std::vector<Thread*> threads_;int num_;std::queue<T> task_queue_;pthread_mutex_t lock;//保护临界区(任务队列)的一把锁pthread_cond_t cond;static ThreadPool<T>* thread_ptr;//静态成员 在类外初始化static pthread_mutex_t mutex ;//静态成员 在类外初始化
};
template<class T>
ThreadPool<T>* ThreadPool<T>::thread_ptr =nullptr;
template<class T>
pthread_mutex_t ThredPool<T>::mutex=PTHREAD_MUTEX_INITIALIZER;//静态的锁不需要手动释放

 问题:

为什么要判断两次呢?

其他线程想要调用该函数时,如果没有最外层的判断就一定会进行申请锁、释放锁的操作。这样写可以有效减少未来必定要加锁检测的问题

2.其他常见的各种锁

  • 悲观锁:在每次取数据时,总是担心数据会被其他线程修改,所以会在取数据前先加锁(读锁,写锁,行锁等),当其他线程想要访问数据时,被阻塞挂起。
  • 乐观锁:每次取数据时候,总是乐观的认为数据不会被其他线程修改,因此不上锁。但是在更新数据前,会判断其他数据在更新前有没有对数据进行修改。主要采用两种方式:版本号机制和CAS操作。
  • CAS操作:当需要更新数据时,判断当前内存值和之前取得的值是否相等。如果相等则用新值更新。若不等则失败,失败则重试,一般是一个自旋的过程,即不断重试。
  • 自旋锁,公平锁,非公平锁?

我们之前学的锁都是悲观锁。

自旋锁:本质就是通过不断的检测状态(一直打电话催促),来进行资源是否就绪的方案。

(互斥锁:只检测一次,临界资源没就绪就直接挂起。)

什么时候使用自旋锁?临界资源就绪的时间短时(是一个相对的概念,取决于场景的容忍度)。

自旋锁的使用

#include <pthread.h>
int pthread_spin_init(pthread_spinlock_t* lock,int pshared);
int pthread_spin_destroy(pthread_spinlock_t* lock);

无论是挂起等待还是自旋本身都是pthread库帮我们做的,我们只需要使用接口。

#include <pthread.h>
int pthread_spin_lock(pthread_spinlock_t* lock);
int pthread_spin_trylock(pthread_spinlock_t* lock); //自旋一次 不成功就返回

 3.读者写者 与消费者生产者的区别

读写锁
公共数据修改的机会比较少。相比较改写,它们读的机会反而高的多。

写独占,读共享,读锁优先级高。

区别:

消费者会取走数据,所以消费者消费者之间是互斥关系。二读者写者是共享关系。

        

相关文章:

Linux--线程安全的单例模式--自旋锁--0211

1. 线程安全的单例模式 1.1 什么是单例模式 某些类, 只应该具有一个对象(实例), 就称之为单例. 1.1.1 懒汉方式实现单例模式 以上篇博文的线程池为例 Liunx--线程池的实现--0208 09_Gosolo&#xff01;的博客-CSDN博客 实现懒汉模式首先要先将构造函数私有化&#xff0c;…...

图文解说S参数(进阶篇)

S参数是RF工程师/SI工程师必须掌握的内容&#xff0c;业界已有多位大师写过关于S参数的文章&#xff0c;即便如此&#xff0c;在相关领域打滚多年的人&#xff0c; 可能还是会被一些问题困扰着。你懂S参数吗? 图文解说S参数&#xff08;基础篇&#xff09; 请继续往下看...台湾…...

Sentinel源码阅读

基础介绍 Sentinel 的使用可以分为两个部分: 核心库&#xff08;Java 客户端&#xff09;&#xff1a;不依赖任何框架/库&#xff0c;能够运行于 Java 8 及以上的版本的运行时环境&#xff0c;同时对 Dubbo / Spring Cloud 等框架也有较好的支持&#xff08;见 主流框架适配&…...

2023年浙江食品安全管理员考试真题题库及答案

百分百题库提供食品安全管理员考试试题、食品安全管理员考试预测题、食品安全管理员考试真题、食品安全管理员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 一、判断题 7.&#xff08;重点&#xff09;《餐饮服务食品安全…...

Webstorm 代码没有提示,uniapp 标签报错

问题 项目是用脚手架创建的&#xff1a; vue create -p dcloudio/uni-preset-vue my-project 打开之后&#xff0c;添加view标签警告报错的。代码也没有提示&#xff0c;按官方说法&#xff1a;CLI 工程默认带了 uni-app 语法提示和 5App 语法提示。 但是我这里就是有问题。…...

MySQL-Innodb引擎事务原理

文章目录1.事务介绍2 事务特性3. 事务的实现原理4 redo log 保证持久性5 undo log 保证原子性6 MVCC 概念6.1 隐藏字段6.2 版本链6.3 ReadView6.3.1readview 版本控制规则7 隔离性 实现7.2 隔离性- REPEATABLE READ 可重复读下8 一致性1.事务介绍 事务是一组操作的集合&#xf…...

Linux操作系统学习(了解环境变量)

文章目录环境变量初识除了上述介绍的PATH&#xff0c;还有一些常见的环境变量如&#xff1a;查看环境变量方法 &#xff1a;环境变量的基本概念&#xff1a;本地变量&#xff1a;环境变量初识 环境变量解释起来比较抽象&#xff0c;先看示例&#xff1a; #include <stdio.…...

数据分析思维(六)|循环/闭环思维

循环/闭环思维 1、概念 在很多的分析场景下&#xff0c;我们需要按照一套流程反复分析&#xff0c;而不是进行一次性的分析&#xff0c;也就是说这套流程的结果会成为该流程的新一次输入&#xff0c;从而形成一个闭环&#xff0c;此时的分析思维我们称之为循环/闭环思维。 常…...

C++:类和对象(下)

文章目录1 再谈构造函数1.1 构造函数体赋值1.2 初始化列表1.3 explicit关键字2 static成员2.1 概念2.2 特性3 友元3.1 友元函数&#xff08;流插入&#xff08;<<&#xff09;及流提取&#xff08;>>&#xff09;运算符重载&#xff09;3.2 友元类4 内部类5 匿名对…...

ASP.NET Core MVC 项目 AOP之IResultFilter和IAsyncResultFilter

目录 一:说明 二:IActionFilter同步 三:IAsyncActionFilter异步 一:说明 IResultFilter同步过滤器与IAsyncResultFilter异步过滤器常常被用作于渲染视图或处理结果。 IResultFilter同步过滤器执行顺序: 1:执行控制器中的构造函数,实例化控制器 2:执行具体的Acti…...

jstack排查cpu占用高[复习]

这样就可以看到占用CPU高的代码位置。 总结&#xff1a;就是先查到占用高的应用和具体的线程&#xff0c;然后根据线程到堆积信息查找即可。 不过堆栈信息非十进制&#xff0c;需提前把线程号转为十六进制。 这样就可以看到占用CPU高的代码位置。 总结&#xff1a;就是先查到…...

网络安全-Pyhton环境搭建

网络安全-Pyhton环境搭建 https://www.kali.org/get-kali/#kali-installer-images—kali官网下载地址 python这个东东呢 是目前来说最简单&#xff0c;方便的开源的脚本语言 广泛用于Web开发&#xff0c;AI&#xff0c;网站开发等领域 python要装2和3 为什么要安装两个版本…...

SpringBoot Mybatis 分页实战

pageInfo的属性 pageNum&#xff1a;当前页 pageSize&#xff1a;页面数据量 startRow&#xff1a;当前页首条数据为总数据的第几条 endRow&#xff1a;当前页最后一条数据为总数据的第几条 total&#xff1a;总数据量 pages&#xff1a;总页面数 listPage{}结果集 reasonable …...

计算机断层扫描结肠镜和全自动骨密度仪在一次检查中的可行性

计算机断层扫描结肠镜和全自动骨密度仪在一次检查中的可行性 Feasibility of Simultaneous Computed Tomographic Colonography and Fully Automated Bone Mineral Densitometry in a Single Examination 简单总结&#xff1a; 数据&#xff1a;患者的结肠镜检查和腹部CT检查…...

Java多级缓存是为了解决什么的?

前言   提到缓存&#xff0c;想必每一位软件工程师都不陌生&#xff0c;它是目前架构设计中提高性能最直接的方式。   缓存技术存在于应用场景的方方面面。从网站提高性能的角度分析&#xff0c;缓存可以放在浏览器&#xff0c;可以放在反向代理服务器&#xff0c;还可以放…...

MongoDB--》索引的了解及具体操作

目录 索引—index 索引的类型 索引的管理操作 索引的使用 索引—index 使用索引的原因&#xff1a;索引支持在MongoDB中高效地执行查询。如果没有索引&#xff0c;MongoDB必须执行全集合扫描&#xff0c;即扫描集合中的每个文档&#xff0c;以选择与查询语句匹配的文档。这…...

Python open()函数详解:打开指定文件

在 Python 中&#xff0c;如果想要操作文件&#xff0c;首先需要创建或者打开指定的文件&#xff0c;并创建一个文件对象&#xff0c;而这些工作可以通过内置的 open() 函数实现。open() 函数用于创建或打开指定文件&#xff0c;该函数的常用语法格式如下&#xff1a;file ope…...

CentOS Stream 9尝鲜安装教程

作者&#xff1a;IT圈黎俊杰 一、下载CentOS Stream 9安装介质 在CentOS官网可以下载到CentOS Stream 9的安装介质&#xff0c;正面列出ISO介质的下载链接地址&#xff1a; https://download.cf.centos.org/9-stream/BaseOS/x86_64/iso/CentOS-Stream-9-20221019.0-x86_64-dv…...

Ambire AdEx 2023 年路线图

Ambire AdEx 是为简化 web3 显示广告而建立的&#xff0c;领先于时代。到 2023 年&#xff0c;它将专注于服务用户需求&#xff0c;同时保持其作为区块链隐私解决方案的核心&#xff0c;反对传统的数字广告模式。 回顾 2022 年 2022 年&#xff0c;AdEx 网络处理了超过 1 亿次展…...

两种特征提取方法与深度学习方法对比的小型金属物体分类分析研究

本文讨论了用于对包括螺丝、螺母、钥匙和硬币在内的小型金属物体进行分类的两种特征提取方法的效率&#xff1a;定向梯度直方图 (HOG) 和局部二进制模式 (LBP)。首先提取标记图像的所需特征并以特征矩阵的形式保存。使用三种不同的分类方法&#xff08;非参数 K 最近邻算法、支…...

传奇私服搭建网站的几种方法

搭建网站的几种方法&#xff1a;一些人&#xff0c;连简单的搭建网站都不会&#xff0c;还要请技术帮忙&#xff0c;真是牛B&#xff0c;这里简单介绍下几种办法一&#xff1a;2003系统下&#xff0c;直接使用IIS&#xff0c;这个太简单了&#xff0c;桌面上就有IIS&#xff0c…...

i.MX8MP平台开发分享(clock篇)- 各类clock的注册

专栏目录:专栏目录传送门 平台内核i.MX8MP5.15.71文章目录 1、关键数据结构1.1 clk_hw1.2 clk_hw_onecell_data2.一个clk的注册过程2.1 fixed clk2.2 pll14xx2.3 fixed factor2.4 mux2.5 composite2.6 gate1、关键数据结构 1.1 clk_hw clk_hw是描述一个时钟信息的最小单元。…...

java ssm计算机系统在线考试平台idea

本系统主要包括以下功能模块学生、教师、班级、考试评阅、在线考试、试题内容、考试等模块&#xff0c;通过这些模块的实现能够基本满足日常计算机系统平台的操作。 本文着重阐述了计算机系统平台的分析、设计与实现&#xff0c;首先介绍开发系统和环境配置、数据库的设计&…...

C语言(字符串函数)

这章的内容记得引用<string.h>头文件 目录 1.strlen&#xff08;&#xff09; 2.strcat() 3.strncat() 4.strcmp() 5.strncmp() 6.strcpy() 7.strncpy() 8.sprintf() 8.strchr() 9.strpbrk() 10.strrchr() 11.strstr() 1.strlen&#xff08;&#xff09; 用于统计字符串的…...

Maxwell工作流程详解

要介绍maxwell的工作原理&#xff0c;首先需要讲一下mysql主从复制的原理 mysql主从复制原理&#xff1a; 如上图&#xff0c;左边是master主节点&#xff0c;右边是slave从节点 工作流程&#xff1a; 1.往主节点mysql的数据库中写入数据&#xff0c;产生数据变化&#xff0c…...

13- EM算法与GMM高斯混合 (聚类算法) (算法)

最大期望算法(EM算法) &#xff0c;曾入选“数据挖掘十大算法”中&#xff0c;是最常见的隐变量估计方法&#xff0c;在机器学习中有极为广泛的用途&#xff0c;例如常被用来学习高斯混合模型的参数。EM算法是在概率模型中寻找参数最大似然估计或者最大后验估计的算法&#xff…...

【新】华为OD机试 - 二叉树层次遍历(Python)| 刷完获取OD招聘渠道

二叉树层次遍历 题目 有一棵二叉树 每一个节点用一个大写字母标识 最多26个节点 现有两组字母 分别表示后序遍历(左孩子指向右孩子指向父节点) 和中序遍历(左孩子指向父节点指向右孩子) 请输出层次遍历的结果 输入 输入为两个字符串 分别为二叉树的后序遍历和中序遍历结…...

工作记录------@Accessors(chain = true)引起的BUG,Excel导入时获取不到值

工作记录------Accessors(chain true)引起的BUG&#xff0c;Excel导入时获取不到值 如题所示 背景&#xff1a;在进行文件excel文件导入时&#xff0c;发现实体类获取到的属性值都为null。 框架&#xff1a;com.alibaba.excel 2.2.0的版本。 结论&#xff1a;首先说下结论 如…...

JavaEE-HTTP协议(二)

目录HTTP请求的方法GET方法POST 方法其他方法“报头”User-AgentRefererCookieHTTP响应200 OK404 Not Found403 Forbidden405 Method Not Allowed500 Internal Server Error504 Gateway Timeout302 Move temporarily301 Moved PermanentlyHTTP请求的方法 GET方法 GET 是最常用…...

代理的基本原理和多线程的基本原理

目录爬虫代理常见代理多线程并发和并行Python中的多进程和多线程爬虫时我们不到一杯茶的功夫就出现了403.打开网页一看会说您的IP访问频率太高&#xff0c;出现这种情况是因为网站采取了一些反爬虫措施&#xff0c;限制某个IP在一定时间内的请求次数&#xff0c;如果超过一定的…...

自学网站平面设计/东莞网站推广行者seo08

这是悦乐书的第190次更新&#xff0c;第193篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第49题&#xff08;顺位题号是204&#xff09;。计算小于非负数n的素数的数量。例如&#xff1a; 输入&#xff1a;10 输出&#xff1a;4 说明&#xff1a;有4个素数小于…...

西安机械加工网站建设/厦门人才网最新招聘信息网

在Vue.js中&#xff0c;每一个vue文件都是一个组件&#xff0c;在.vue文件中可以将模板&#xff0c;脚本&#xff0c;样式写在一起&#xff0c;便于组织整个组件。在使用template&#xff0c;script时&#xff0c;编写css样式时&#xff0c;都进行的特别顺利&#xff0c;唯独当…...

和嗲囡囡和做的网站/seo网络推广哪家专业

面向问题&#xff1a;某java文件A中定义类需要被其他文件B中的类调用。 思路&#xff1a;将A文件架包-jar&#xff0c;将-jar导入到B文件中. 新建文件夹bin用于存储jar包 找到jar&#xff0c;用鼠标拖到需要它工程的bin中...

农业网站设计/做关键词优化的公司

其中&#xff0c;红色部分为我们开发人员要做的&#xff0c;其他部分是框架做的。 学习就要搞懂整个运行的流程&#xff01;否则&#xff0c;不利于个人技术的积累&#xff01;...

网站seo搜索引擎优化教程/百度招聘2022年最新招聘

【题目】A. A String Game 【题意】给定目标串S和n个子串Ti&#xff0c;Alice和Bob轮流选择一个子串操作&#xff0c;必须且只能在子串末尾添加一个字符使得新串也是S的子串&#xff0c;不能操作即输&#xff0c;求胜利者。|S|<10^5,n<100。多组数据&#xff0c;保证Σ|S…...

专业优化网站排名/2022年最火的电商平台

原文来源&#xff1a;Salesforce Researc 作者&#xff1a;JiataoGu、 James Bradbury 「雷克世界」编译&#xff1a;嗯~阿童木呀、多啦A亮 Salesforce研究院去年了成立研究院&#xff0c;之后又发布其人工智能服务Einstein AI。该研究院在自然语言处理&#xff0c;尤其是翻译方…...