Linux 线程同步——信号量、互斥锁、读写锁

news2024/11/18 12:40:00

一、线程同步的概念

这里的同步就是对程序的执行进行控制,因为如果不进行控制就会出现错误的问题,这里的控制是为了保证程序的正确性。

线程同步指的是当一个线程在对某个临界资源进行操作时,其他线程都不可以对这个资源进行操作,直到该线程完成操作, 其他线程才能操作,也就是协同步调,让线程按预定的先后次序进行运行。

线程同步的方法有四种:互斥锁、信号量、条件变量、读写锁。

二、信号量

1.信号量的应用引入示例

代码如下:

在这里插入图片描述

运行结果:

第一次运行结果:
在这里插入图片描述

第二次运行结果:

在这里插入图片描述

由结果可以看出,并不是每个线程每次输出的都是5000,而是会有低于5000的情况,这是因为可能会有两个线程在并行运行的时候同时去访问变量g_count,两个线程拿到的g_count的值是相同的,同时执行g_count++,这样就会导致两个线程并不会把g_count的值分别加两次,属于两个线程同时对g_count加1,相当于g_count只加了一次,就会使我们少一个数字。

使用信号量解决上面这一问题。

2.信号量函数

线程中使用的基本信号量函数有4个。

(1)sem_init()初始化信号量

在这里插入图片描述

参数解释:

第一个参数sem:信号量的变量。

第二个参数pshared:控制信号量的类型,如果其值为0,就表示整个信号量是当前进程的局部信号量,不让该信号量在多个进程之间共享。否则这个信号量就可以在多个进程之间共享。一般设置为0,不让信号量在进程间共享。

第三个参数value:无符号类型,设置信号量的初始值。

(2)sem_wait()P操作

在这里插入图片描述

参数解释:

参数sem:传所定义的信号量的地址。
该将对该信号量执行P(-1)操作。

(3)sem_post()V操作

在这里插入图片描述

参数解释:

参数sem:传所定义的信号量的地址。
该函数将对该信号量执行V(+1)操作。

(4)sem_destroy()销毁信号量

在这里插入图片描述

参数解释:

参数sem:传所定义的信号量的地址。

该函数将销毁所指向的信号量。

3.信号量的具体应用

将上述示例中的代码修改之后如下:

在这里插入图片描述

运行结果:

在这里插入图片描述

此时,在每一个线程中都加入了信号量,在g_count++之前进行p操作获取资源,如果获取不到则说明另外四个线程中的其中一个正在使用信号量,使用完之后执行了v操作,这时当前这个线程才可以成功执行p操作,才可以执行g_count++操作,执行完g_count++操作之后再执行v操作释放资源,此时其他线程才可以使用信号量。这样就避免了两个或者多个线程同时获取g_count的值进行++操作,然后导致g_count的值只被加了一次。这样就会输出正确的g_count在5个线程中加了1000次之后的值5000。

三、互斥锁

1.互斥锁的概念

互斥锁也称为互斥量,互斥锁是多线程程序中的同步访问方法的一种。互斥锁允许程序员锁住某一个对象,使得每次只能有一个线程访问它。为了控制对关键代码的访问,必须在进入这段代码之前设置一个互斥锁,然后在完成操作之后解锁它。

【注意】加锁会使程序的性能下降,但是可以保证程序的正确性。

2.互斥锁函数

(1)pthread_mutex_init()初始化互斥锁

在这里插入图片描述

参数解释:

第一个参数mutex:传入互斥锁变量的地址。
第二个参数mutexattr:互斥锁的属性,一般传NULL。

(2)pthread_mutex_lock()加锁

这个函数又可能发生阻塞,如果发现锁已经被加上了,这个时候就加锁不成功,就会发生阻塞。

在这里插入图片描述

参数解释:

参数mutex:传入所定义的互斥锁变量的地址。为该互斥锁加锁。

(3)pthread_mutex_unlock()解锁

在这里插入图片描述

参数解释:

参数mutex:传入所定义的互斥锁变量的地址。为该互斥锁解锁。

(4)pthread_mutex_destory()销毁锁

在这里插入图片描述

参数解释;

参数mutex:传入所定义的互斥锁变量的地址。销毁该互斥锁。

3.互斥锁的应用

代码如下:

在这里插入图片描述

运行结果:

在这里插入图片描述

在这个程序中,互斥锁的使用和信号量一样,在每一个线程中都加入了互斥锁,在g_count++之前执行加锁操作,使每次只能有一个线程访问变量g_count,如果访问不到则说明已经被别的线程加锁,这时当前这个线程不可以对锁着的变量g_count进行++操作,会发生阻塞,只有等别的线程对变量g_count解锁之后,当前的线程才可以成功执行加锁操作,才可以执行g_count++操作,执行完g_count++操作之后再执行解锁操作,此时其他线程才可以继续对变量g_count进行加锁操作。这样就避免了两个或者多个线程同时获取g_count的值进行++操作,然后导致g_count的值只被加了一次。这样就会输出正确的g_count在5个线程中加了1000次之后的值5000。

四、读写锁

1.读写锁的引入

但是有些场景,加锁并不是为了去修改数据,而是为了读取数据。比如说有一些线程要读取数据,有一些线程要修改数据,如果一个线程想读取,另外一个线程想修改,那么这两个线程肯定是不能同时执行的;如果两个线程都想修改数据,那么这两个线程也不可以同时执行;但是如果两个线程都想读取数据,这时这两个线程就可以同时执行。

而在程序中我们大量的需求可能只是读取数据,偶尔会修改数据。对于互斥锁来说,一旦加锁,就知道当前那个线程读取数据,别的线程都不可以读取数据,这样的话比较繁琐。如果使用读写锁,就可以在一定程度上把力度分的更细一点,这样的话读取数据的时候,多个线程可以同时执行,同时读取数据。如果要修改数据的话,就不可以,就会阻塞,必须要等别的线程读取完数据之后才可以修改数据。

2.读写锁函数

(1)pthread_rwlock_init()初始化读写锁

在这里插入图片描述

(2)pthread_rwlock_rddlock()加读锁

在这里插入图片描述

(3)pthread_rwlock_wrlock()加写锁

在这里插入图片描述

(4)pthread_rwlock_unlock()解锁

无论哪个锁,都可以解

在这里插入图片描述

(5)pthread_rwlock_destroy()销毁锁

在这里插入图片描述

3.读写锁的使用

代码如下:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/905831.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自然语言处理: 第九章DeepSpeed的实践

理论基础 仓库链接: microsoft/DeepSpeed: DeepSpeed is a deep learning optimization library that makes distributed training and inference easy, efficient, and effective. DeepSpees正如它官网介绍的一样,它为深度学习模型提供了一站式的快速以及大规模…

【SA8295P 源码分析】03 - SA8295P QNX Host上电开机流程分析

【SA8295P 源码分析】03 - SA8295P QNX Host上电开机流程分析 一、阶段1 固件开机自检 (SM BIST):APPS PBL加载XBL后触发 INT_RESET进行Warm Reset二、阶段2 固件开机自检 (SM BIST):加载TZ,初始Hypervisor,启动QNX Kernel&#x…

k8编写yaml文件小工具

在刚接触k8s的时候觉得yaml资源文件非常的难写,完全看不懂,经过一段时间的摸索学习,发现k8s平台中是提供了一系列的工具和技巧的,可以帮助我们很好的编写资源文件,提升编写yaml文件的能力,常用的命令工具是…

python爬虫9:实战2

python爬虫9:实战2 前言 ​ python实现网络爬虫非常简单,只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点,方便以后复习。 申明 ​ 本系列所涉及的代码仅用于个人研究与讨论,并不会对网站产生不好…

时序预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现SO-CNN-LSTM蛇群算法优化卷积长短期记忆神经网络时间序列预测预测效果基本介绍程序设计学习总结参考资料 预测效果 基本介绍 时序预测 | MATLAB实现SO-CNN-LSTM蛇群…

深入解析淘宝API,实现高效商务应用

淘宝API的基本调用 1. API文档与SDK 淘宝API官方提供了详细的API文档,包含了API的使用说明、参数列表、示例代码等内容。开发者可以通过文档了解每个API接口的具体功能和使用方法。此外,淘宝API还提供了多种编程语言的SDK,方便开发者进行快速…

桌游新篇:3.1 UserCase分析

距离上一次停止更新这个系列有将近9个月了。 工作这么久,学会了一件事,就是想清楚再动手。当然,后续工作已经渐渐展开了,而且当下属于天时地利人和(既有当前MR设备带来的硬件buff,又有大语言模型&#xff…

SOPC之NIOS Ⅱ实现电机转速PID控制

通过FPGA开发板上的NIOS Ⅱ搭建电机控制的硬件平台,包括电机正反转、编码器的读取,再通过软件部分实现PID算法对电机速度进行控制,使其能够渐近设定的编码器目标值。 一、PID算法 PID算法(Proportional-Integral-Derivative Algo…

21-注意点说明:scoped样式冲突 / data

组件的三大组成部分 - 注意点说明 组件的样式冲突 scoped 默认情况:写在组件中的样式会 全局生效 -> 因此很容易造成多个组件之间的样式冲突问题 1.全局样式: 默认组件中的样式会作用到全局 2.局部样式: 可以给组件加上 scoped 属性,可以让样式只作用于当前组件 scoped原理…

《有效调节情绪,保持工作心态平和》

工作中,我们有时会遇到各种挑战和困难,这些挑战和困难可能引发我们的负面情绪,例如焦虑、愤怒和沮丧等。然而,保持稳定的情绪是实现高效工作的重要因素之一。本文将分享如何在工作中保持稳定的情绪。 首先,让我们来谈谈…

Spring Boot 如何通过jdbc+HikariDataSource 完成对Mysql 操作

😀前言 本篇博文是关于Spring Boot 如何通过jdbcHikariDataSource 完成对Mysql 操作的说明,希望你能够喜欢😊 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的…

Python多组数据三维绘图系统

文章目录 增添和删除坐标数据更改绘图逻辑源代码 Python绘图系统: 基础:将matplotlib嵌入到tkinter 📈简单的绘图系统 📈数据导入📈三维绘图系统自定义控件:坐标设置控件📉坐标列表控件 增添和…

录屏有哪些讲究?有哪些好用的录屏软件?

在如今数字时代,视频分享已经成为一种流行的传播方式。为了制作高质量的视频内容,录屏已经成为了一种必备的技能。但是,要想制作出令人满意的录屏视频,需要了解一些讲究和使用一些好用的录屏软件。 录屏是一种视觉传达方式&#x…

【prism】发布订阅和取消订阅,进一步梳理

一个对象对应一个事件订阅 一个事件是可以被重复订阅的,如果一个事件被订阅了三次,那边发布一次该事件,就会触发三次事件订阅: 通过观察Prism的事件聚合器对象,发现它此时包含了三个事件对象,其中第三个事件订阅数量达到了3! 这样的话,如果调用一次 Publish ,那么S…

Android 获取 SHA256 签名

在 Android Studio 中的 Terminal ,输入命令: keytool -list -v -keystore debug.keystore 如果出现以下提示: keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -validity 10000 按照提示输入相关信息,…

SIP 7英寸触摸屏寻呼主机

SV-8006TP SIP7英寸触摸屏寻呼主机 一、描述 SV-8006TP是我司的一款SIP桌面式对讲广播主机,具有10/100M以太网接口,从网络接口接收网络的音频数据,提供立体声音频输出。 SV-8006TP寻呼话筒可以通过麦克风或者本地线路输入对终端进行分区广…

Java【手撕双指针】LeetCode 283. “移动零“, 图文详解思路分析 + 代码

文章目录 前言一、移动零1, 题目2, 思路分析3, 代码展示 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: 📕 JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等 📗 Java数据结构: 顺序表, 链表,…

传统图像处理之直方图均衡化

重要说明:本文从网上资料整理而来,仅记录博主学习相关知识点的过程,侵删。 一、参考资料 直方图均衡化的原理及实现 图像处理之直方图均衡化 二、直方图 1. 直方图的概念 图像的灰度直方图,描述了图像中灰度分布情况&#xf…

BaiChuan13B多轮对话微调范例

前方干货预警:这可能是你能够找到的,最容易理解,最容易跑通的,适用于多轮对话数据集的大模型高效微调范例。 我们构造了一个修改大模型自我认知的3轮对话的玩具数据集,使用QLoRA算法,只需要5分钟的训练时间…

antd5源码调试环境启动(MacOS)

将源码下载至本地 这里antd5 版本是5.8.3 $ git clone gitgithub.com:ant-design/ant-design.git $ cd ant-design $ npm install $ npm start前提:安装python3、node版本18.14.0(这是本人当前下载的版本) python3安装教程可参考:https://…