1、什么是互斥锁

        如果信号量的值最多为 1,那实际上相当于一个共享资源在任意时刻最多只能有一个线程在访问,这样的逻辑被称为“互斥”。这时,有一种更加方便和语义更加准确的工具来满足这种逻辑,他就是互斥锁

        “锁”是一种非常形象的说法:就像一个房间只能住一个人一样,任何人进去之后就把门锁上了,其他任何人都不能进去,直到进去的那个人重新开开锁,即释放了这个锁资源为止。

        互斥锁用于保护线程中某一个共享资源, 该资源在任意一个时刻只允许有一个线程可以访问的情况。互斥锁是专门用于处理线程互斥的一种方式,它有两种状态:上锁状态、解锁状态。

        例如有多个线程有可能会对某一个链表进行删除、插入的操作。那么任何一个线程想要操作该链表前都应该使用互斥锁来阻塞等待操作的权限(pthread_mutex_lock),当获得权限后上锁,阻止其他线程来同时访问该链表造成链表的错乱。当操作结束后使用解锁函数(pthread_mutex_unlock)把锁资源释放出来。

        特点: 如果互斥锁处于上锁状态,那么再上锁就会造成阻塞,直到这把锁解开了之后,才能上锁。解锁状态依然继续解锁,不会阻塞。

2、线程互斥锁API接口

(1)、定义互斥锁变量

        数据类型: pthread_mutex_t

pthread_mutex_t m;

(2)、初始化互斥锁

#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *attr);参数:mutex: 未初始化过互斥锁变量的地址mutexattr:普通属性,NULL
返回值:成功:0失败:非0错误码

        静态初始化:

pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
也就是说,以上这句话等价于:
pthread_mutex_t m;
pthread_mutex_init(&m,NULL);

(3)、线程上锁

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
参数:mutex:互斥锁变量的地址
返回值:成功:0失败:非0错误码

(4)、线程解锁

#include <pthread.h>
int pthread_mutex_unlock(pthread_mutex_t *mutex);
参数:mutex:互斥锁变量的地址
返回值:成功:0失败:非0错误码

(5)、销毁互斥锁

#include <pthread.h>
int pthread_mutex_destroy(pthread_mutex_t *mutex);
参数:mutex:互斥锁变量的地址
返回值:成功:0失败:非0错误码

3、互斥锁应用实例

        互斥锁使用场景:当我们使用一些临界资源时,防止多个线程同时访问,我们可以这么做,在访问临界资源前,让线程先上锁,然后再访问资源,访问完了之后就解锁,让别的线程去上锁。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>int g_val = 0;
//1)定义互斥锁变量。 -----》数据类型  pthread_mutex_t 
pthread_mutex_t mutex;//线程的例程函数,也就是创建线程之后,去执行这个函数
void* routine1(void *arg)
{pthread_mutex_lock(&mutex);//上锁//写操作,修改内存空间的值 g_val = 100;int i;for(i=0; i<5; i++){sleep(1);    g_val += g_val*i;printf("%d  routine1 100  g_val:%d\n",i,g_val);        }pthread_mutex_unlock(&mutex);//解锁
}//线程的例程函数,也就是创建线程之后,去执行这个函数
void* routine2(void *arg)
{pthread_mutex_lock(&mutex);//上锁//写操作,修改内存空间的值 g_val = 200;int i;for(i=0; i<5; i++){sleep(1);    g_val += g_val*i;    printf("routine2 200  g_val:%d\n",g_val);        }pthread_mutex_unlock(&mutex);//解锁
}//线程的例程函数,也就是创建线程之后,去执行这个函数
void* routine3(void *arg)
{pthread_mutex_lock(&mutex);//上锁int i;//读操作,此时仅仅只是将这个值打印出来for(i=0; i<5; i++){sleep(1);        printf("routine3  g_val:%d\n",g_val);        }pthread_mutex_unlock(&mutex);//解锁
}//线程的例程函数,也就是创建线程之后,去执行这个函数
void* routine4(void *arg)
{pthread_mutex_lock(&mutex);//上锁int i;//读操作,此时仅仅只是将这个值打印出来for(i=0; i<5; i++){sleep(1);        printf("routine4  g_val:%d\n",g_val);        }pthread_mutex_unlock(&mutex);//解锁
}int main(int argc, char **argv)
{//2)初始化 互斥锁pthread_mutex_init(&mutex,NULL);// 创建一个新的线程1pthread_t thread1;    pthread_create(&thread1,NULL,routine1,NULL);                      // 创建一个新的线程2pthread_t thread2;    pthread_create(&thread2,NULL,routine2,NULL);    // 创建一个新的线程3pthread_t thread3;    pthread_create(&thread3,NULL,routine3,NULL);                      // 创建一个新的线程4pthread_t thread4;    pthread_create(&thread4,NULL,routine4,NULL);    //接合子线程 --阻塞等待子线程退出 回收资源pthread_join(thread1,NULL);pthread_join(thread2,NULL);pthread_join(thread3,NULL);pthread_join(thread4,NULL);//5)销毁互斥锁pthread_mutex_destroy(&mutex);return 0;
}

        如下图所示为互斥锁程序的演示结果。从终端打印输出的信息,可以看到每个线程都是依次有序的排队进行获取释放互斥锁进行运行的。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据文件写入技术详解:从CSV到Excel的ETL流程优化

文章大纲&#xff1a; 引言&#xff1a;数据文件写入在ETL流程中的重要性 在现代数据处理中&#xff0c;ETL&#xff08;提取、转换、加载&#xff09;流程是数据分析和业务决策的核心环节&#xff0c;而数据文件写入作为ETL的最后一步&#xff0c;扮演着至关重要的角色。它不…

在Cline中使用Gemini CLI,图形化界面操作:从命令行到可视化操作的全新体验,爽炸天!

在软件开发的进程中&#xff0c;命令行工具虽功能强大&#xff0c;但对部分开发者而言&#xff0c;图形化界面的直观与便捷性有着独特魅力。此前&#xff0c;Cline 新版本集成 Gemini CLI 的消息在开发者社群引发热议&#xff0c;尤其对于偏好图形界面的开发者来说&#xff0c;…

正交视图三维重建 笔记 2d线到3d线

这种代码怎么写好&#xff0c;x1tx1 x2tx2 x1x2在一条线上tx2和tx1在一条线上输出x1 y1 ty1&#xff0c;x2 y2 ty2 线过的点 的集合 俯视图找深度 测试一下 目标 四条线变一条线 复杂度贼大跑起来贼慢 加了16000条 去重 for (const [x1, y1, x2, y2, lineId, type] of front…

【耳机】IEM 前腔 后腔 泄压孔 -> 调音纸对频响曲线的影响

一、后腔 1.曲线说明 绿色&#xff1a;无调音纸 红色&#xff1a;使用Y3 粉色&#xff1a;使用Y6 2.结论 后腔是负责微调的&#xff0c;阻尼大小和低频升降成 反比。 阻 大 -> 低频 降低 阻 小 -> 低频 升高 二、前腔 1.曲线说明 红色&#xff1a;无调音纸 黄色&am…

信息安全与网络安全---引言

仅供参考 文章目录 一、计算机安全1.1 CIA三元组1.2 影响等级1.3 计算机安全的挑战 二、OSI安全体系结构2.1 安全攻击2.2 安全服务2.3 安全机制 三、基本安全设计准则四、攻击面和攻击树&#xff08;重点&#xff09;4.1 攻击面4.2 攻击树 五、习题与答案 一、计算机安全 &…

C# VB.NET取字符串中全角字符数量和半角字符数量

C# VB.NET中Tuple轻量级数据结构和固定长度数组-CSDN博客 https://blog.csdn.net/xiaoyao961/article/details/148872196 下面提供了三种统计字符串中全角和半角字符数量的方法&#xff0c;并进行了性能对比。 性能对比&#xff08;处理 100 万次 "Hello&#xff0c;世界…

CC++公司面试题[个人总结,持续更新中]

嵌入式初级面试题 姓名: 日期: 开始时间: (答题时间60分钟,答题过程中请不要上网查询资料,不可带走答卷) 1:设float a=2,b=4,c=3;,以下C语言表达式与代数式(a+b)+c计算结果不一致的是( )[3分] A.(a+b)c/2 B. (1/2)*(a+b)c C. (a+b)c*1/2 D.c/2(a+b) 2:为了向二进制文件尾部…

Qt QGraphics简述及例程 - QGraphicsView、QGraphicsScene和QGraphicsItem

Qt QGraphics简述及例程 引言一、简单例程二、关于坐标系问题 引言 QGraphics*是Qt框架中&#xff0c;主要用于处理2D图形项的显示、交互和管理的模块&#xff0c;包括QGraphicsView、QGraphicsScene和QGraphicsItem。提供了一套高效的场景-视图架构&#xff0c;适合开发复杂的…

代码随想录打卡第一天

文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode&#xff1a;704. 二分查找_哔哩哔哩_bilibili class Solution { public:int search(vector<int>& nums, int target) {int left0;//左边界int…

时序数据库全面解析与对比

文章目录 1. 时序数据库概述1.1 时序数据特点1.2 时序数据库核心功能 2. 主流时序数据库对比2.1 InfluxDB2.2 Prometheus2.3 TimescaleDB2.4 OpenTSDB2.5 TDengine 3. 全方位对比3.1 功能对比3.2 性能对比3.3 适用场景对比3.4 社区与生态 4. 选型建议4.1 根据数据规模选择4.2 根…

【STM32CubeMX】ST官网MCU固件库下载及安装

用STM32CubeMX自带的Updater更新固件包会遇到各种幺蛾子&#xff08;如下图所示&#xff09;&#xff0c;所以干脆自己下载固件包&#xff0c;快速升级固件。 1. ST官网搜索你需要的MCU型号&#xff0c;并选择需要的固件版本&#xff0c;我这里是H7的MCU所以就找H7&#xff08;…

青少年编程与数学 01-012 通用应用软件简介 13 网上学习资源

青少年编程与数学 01-012 通用应用软件简介 13 网上学习资源 一、什么是网上学习资源&#xff08;一&#xff09;网上学习资源的基本定义&#xff08;二&#xff09;网上学习资源的工作原理&#xff08;三&#xff09;网上学习资源的类型 二、网上学习资源的重要意义&#xff0…

Python Selenium 忽略证书错误

文章目录 Python Selenium 忽略证书错误和忽略&#x1f527; **一、忽略 SSL 证书错误**1. **基础配置&#xff08;适用于 Chrome/Firefox&#xff09;**2. **高级场景&#xff1a;指定证书指纹**3. **浏览器兼容方案** &#x1f507; **二、隐藏 DevTools 监听提示**1. **禁用…

YOLOv8模型在RDK5开发板上的部署指南:.pt到.bin转换与优化实践

以下是针对在RDK5开发板(基于NVIDIA Jetson Orin平台)部署YOLOv8模型的详细技术指南,涵盖从模型转换、优化到部署的全流程: YOLOv8模型在RDK5开发板上的部署指南:.pt到.bin转换与优化实践 ——基于TensorRT的高性能嵌入式部署方案 第一章:技术背景与核心概念 1.1 RDK5开…

内网横向-工作流

一、信息收集阶段 操作 工具 / 命令 说明 系统基础信息采集 systeminfo、whoami /user 查看系统版本、用户 SID 等 域内用户 / 组查询 net user /domain、net group "domain admins" /domain 列出域用户及管理员组 域控及网络结构探测 nltest /dsgetdc、ip…

个人日记本小程序开发方案(使用IntelliJ IDEA)

个人日记本小程序开发方案(使用IntelliJ IDEA) 一、项目创建与环境配置 1. 新建项目 打开IDEA → New Project → JavaFX选择JDK 11+版本添加必要依赖:<!-- pom.xml --> <dependencies><dependency><groupId

react快速开始项目模板

代码仓库 gitee 创建项目 首先保证安装了node, 然后使用vite创建项目 vite npm create vite react-learn cd react-learn npm i 目录结构 一个完整的前端项目需要: 状态管理 在全局维护共有的状态(数据), 让页面组件之间共享数据, 我们使用pinia路由 路由让页面之间可以…

scrapy+django+pyecharts+mysql 实现西安游客行为分析系统大屏_用户画像_空间分析_路线智能推荐

项目地址 link 此处展示部分结果 思路 描述性统计 可视化大屏 用户画像&#xff08;聚类&#xff0c;情感分析&#xff09; 空间分析

AC-DC-AC间接变频电源设计方案(工频50Hz→20KHz)

AC-DC-AC间接变频电源设计方案(工频50Hz→20KHz) 一、方案分析与选择 1. 可选电路结构分析 方案1:二极管整流+Boost PFC+全桥逆变 优点: 输入功率因数高(>0.99)直流电压稳定可控输出波形质量好缺点: 电路复杂度较高成本相对较高方案2:晶闸管相控整流+电容滤波+半…

七天学完十大机器学习经典算法-09.梯度提升算法:预测艺术的精进之道

接上一篇《七天学完十大机器学习经典算法-08.K均值聚类&#xff1a;无监督学习的万能分箱术》 想象你在教一个学生解决复杂数学题&#xff1a;先让他做基础题&#xff0c;然后针对错误部分强化练习&#xff0c;再针对新错误继续训练...如此反复精进&#xff0c;直到完美掌握——…