Linux的线程同步

article/2025/8/28 15:10:56

一、互斥锁(互斥量)

互斥锁是一种特殊的变量,有上锁(lock)和解锁(unlock)两种状态。

当处于解锁状态时,线程想获取该互斥锁,就可以获取不被阻塞,互斥锁变为锁定状态;

当处于锁定状态时,线程获取互斥锁被阻塞,并加入到这个互斥锁的等待队列中。

互斥锁有点像打印机,空闲时你可以打印;别人在打印时,你就需要排队等待打印机空闲。

1.1 创建并初始化一个互斥锁

使用 pthread_mutex_t 类型的变量来表示互斥锁。在使用之前,必须对其进行初始化。

静态初始化:

pthread_mutex_t mutex =PTHREAD_MUTEX_INITIALIZER;

动态初始化:

pthread_mutex_init 函数

一般我们都使用静态初始化。

理由:

静态初始化通常比 pthread_mutex_init 更有效,而且可以在定义为全局变量时即完成初始化,这样可以保证在任何线程开始执行之前,初始化既已完成。

 1.2 互斥锁相关属性及分类

//初始化互斥锁属性

//初始化互斥锁属性
pthread_mutexattr_init(pthread_mutexattr_t attr);//销毁互斥锁属性
pthread_mutexattr_destroy(pthread_mutexattr_t attr);//用于获取互斥锁属性
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr ,int *restrict pshared);//用于设置互斥锁属性
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr ,int pshared);

attr表示互斥锁的属性,pshared表示互斥锁的共享属性,有两种取值:

1)PTHREAD_PROCESS_PRIVATE:锁只能用于一个进程内部的两个线程进行互斥(默认情况)

2)PTHREAD_PROCESS_SHARED:锁可用于两个不同进程中的线程进行互斥,使用时还需要在进程共享内存中分配互斥锁,然后该互斥锁指定属性就可以了。

 1.3 互斥锁常用函数

// 销毁互斥锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);// 对互斥锁的锁定
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);// 对互斥锁的解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);

pthread_mutex_lock函数会调用这个函数线程一直阻塞到互斥锁可用为止,而pthread_mutex_trylock会立即返回

注意事项:

  1. 尽量保持锁的粒度,越小越好。(访问共享数据,加锁。访问家属【立即】解锁。)

  2. 互斥锁本质是结构体,可以看成整数,初值为1。(当pthread_mutex_init 函数调用成功。)

  3. 加锁:--操作,阻塞线程。

  4. 解锁:++操作,唤醒阻塞在锁上的线程。

二、信号量

  信号量广泛用于进程或线程间的同步或互斥,信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。

  根据信号量的值来判断是否对公共资源具有访问权限,当信号量的值大于0时,可以访问,否则将阻塞。相当于初始化值为N的互斥量。N值,表示可以同时访问共享数据区的线程数。

带有两个原子操作 P 和 V,一次 P 操作使信号量减1,一次 V 操作使信号量加 1。

函数: 

sem_t sem     //定义类型

初始化信号量

int sem_init(sem_t *sem, int pshared, unsigned int value);
参数:

sem 信号量

pshared        0:用于线程间同步

                     1:用于进程间同步

value:        N值:指定同时访问的线程数

#include <semaphore.h>// 信号量 P 操作(减 1)
int sem_wait(sem_t *sem);// 以非阻塞的方式来对信号量进行减 1 操作
int sem_trywait(sem_t *sem);// 信号量 V 操作(加 1)
int sem_post(sem_t *sem);// 获取信号量的值
int sem_getvalue(sem_t *sem, int *sval);// 销毁信号量
int sem_destroy(sem_t *sem);

// 信号量用于同步实例
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>sem_t sem_g,sem_p;   //定义两个信号量
char ch = 'a';void *pthread_g(void *arg)  //此线程改变字符ch的值
{while(1){sem_wait(&sem_g);ch++;sleep(1);sem_post(&sem_p);}
}void *pthread_p(void *arg)  //此线程打印ch的值
{while(1){sem_wait(&sem_p);printf("%c",ch);fflush(stdout);     // 刷新标准输出缓冲区sem_post(&sem_g);}
}int main(int argc, char *argv[])
{pthread_t tid1,tid2;sem_init(&sem_g, 0, 0); // 初始化信号量为0sem_init(&sem_p, 0, 1); // 初始化信号量为1// 创建两个线程pthread_create(&tid1, NULL, pthread_g, NULL);pthread_create(&tid2, NULL, pthread_p, NULL);// 回收线程pthread_join(tid1, NULL);pthread_join(tid2, NULL);return 0;
}


http://www.hkcw.cn/article/PkokyodkIo.shtml

相关文章

.NET WinForm图像识别二维码/条形码

需求:图像识别出一张图片中的二维码或者条形码&#xff0c;并读取其中的内容。 一、安装ZXing.NET(此处建议使用0.14.0&#xff0c;高版本的不少地方进行优化&#xff0c;如果能处理好也可) Install-Package ZXing.Net 二、WinForm示例代码&#xff08;含关键优化&#xff0…

理解教材意图轻松积累常见数列

教学感悟 以前在传授数列时只是机械的要求学生记住常见的数列&#xff0c;至于“哪些才算是常见的数列&#xff1f;这些数列是怎么来的”&#xff0c;心里比较糊涂&#xff0c;在有一次的教学中&#xff0c;偶然回忆起&#xff1a;函数教学时教材要求掌握一些常见的函数&#…

[预训练]Encoder-only架构的预训练任务核心机制

原创文章1FFN前馈网络与激活函数技术解析&#xff1a;Transformer模型中的关键模块2Transformer掩码技术全解析&#xff1a;分类、原理与应用场景3【大模型技术】Attention注意力机制详解一4Transformer核心技术解析LCPO方法&#xff1a;精准控制推理长度的新突破5Transformer模…

【大模型MCP】MCP 深度解析:AI 时代的「USB-C」接口——原理、对比、实战代码与行业落地

摘要 模型上下文协议 (Model Context Protocol, MCP) 诞生于 2024 年11月&#xff0c;由 Anthropic 牵头&#xff0c;在 2025-03-26 发布 1.0 正式规范。它以 JSON-RPC 2.0 消息结构承载于 WebSocket / SSE 等全双工传输之上&#xff0c;把「初始化 → 工具目录 → 调用 → 结…

超声波清洗机的作用是什么?使用超声波清洗机可以去除毛刺吗?

在现代制造业中&#xff0c;表面质量对产品的性能和外观至关重要。超声波清洗机作为一种高效的清洗工具&#xff0c;在去除表面污垢和缺陷方面发挥着关键作用。本文深圳科伟达将介绍超声波清洗机的作用&#xff0c;以及它是否能够有效去除毛刺。 超声波清洗机的作用&#xff1…

非常好看网站维护带倒计时模板+维护结束模板

非常好看网站维护带倒计时模板维护结束模板 网站维护带倒计时模板维护结束模板.zip - 蓝奏云

STM32F103_Bootloader程序开发05 - Keil修改生成文件的路径与文件名,自动生成bin格式文件

导言 通过Keil的相关配置&#xff0c;可以灵活地修改输出文件的保存路径及文件名称。在Bootloader程序开发过程中&#xff0c;合理配置输出文件对于后续固件升级和自动化脚本处理至关重要。完成路径和文件名配置后&#xff0c;还可以借助Keil自带的fromelf.exe工具&#xff0c;…

【MQ】消息队列的核心价值及技术选型

文章目录 一、什么是消息队列二、消息队列的核心功能三、主流消息队列技术对比ActiveMQ&#xff1a;逐渐淡出的老牌产品Kafka&#xff1a;大数据领域的王者RabbitMQ&#xff1a;企业级可靠选择Apache Pulsar&#xff1a;云原生时代的"新贵"NATS&#xff1a;轻量级消息…

本地部署消息代理软件 RabbitMQ 并实现外部访问( Windows 版本 )

RabbitMQ 是由 Erlang 语言开发的 消息中间件&#xff0c;是一种应用程序之间的通信方法。支持多种编程和语言和协议发展&#xff0c;用于实现分布式系统的可靠消息传递和异步通信等方面。 本文将详细介绍如何在 Windows 系统本地部署 RabbitMQ 并结合路由侠实现外网访问本…

如何在 Odoo 18 中创建 PDF 报告

如何在 Odoo 18 中创建 PDF 报告 Qweb 是 Odoo 强大的模板引擎&#xff0c;旨在轻松将 XML 数据转换为 HTML 文档。其功能特性包括基于属性的自定义、条件逻辑、动态内容插入及多样化的报告模板选项。这种多功能性使 Qweb 成为制作个性化、视觉吸引力强的报告、电子邮件和文档…

【面板数据】上市公司供应链网络地位数据(2001-2024年)

企业是产业链供应链的微观主体&#xff0c;其供应链网络布局是增强产业链供应链稳定性的重中之重&#xff0c;企业在供应链网络中的地位&#xff0c;已成为衡量其市场影响力和风险承受能力的重要指标。本次是上市公司供应链网络地位数据&#xff0c;数据年份为2001-2024年。 一…

EasyFileCount(文件查重工具) v3.0.5.1 便携版

EasyFileCount 是一款免费方便、快捷的文件管理软件&#xff0c;采用Java开发&#xff0c;主打一个清爽简洁、安全无害的使用体验&#xff0c;支持多盘高性能扫描。遍历扫描文件夹的速度还算比较快的&#xff0c;当然所谓的快慢取决于CPU、系统、硬盘种类、文件或文件夹的数量等…

【在线五子棋对战】一、项目简介 环境搭建

文章目录 Ⅰ. 项目简介Ⅱ. 开发环境Ⅲ. 核心技术Ⅳ. 环境搭建① CentOS-7.6环境搭建1、安装wget工具2、更换软件源3、安装第三方软件源4、安装lrzsz传输工具5、安装高版本gcc/g编译器6、安装gdb调试器7、安装git8、安装cmake9、安装boost库10、安装Jsoncpp库11、安装MySQL数据库…

MFC坦克大战游戏制作

MFC坦克大战游戏制作 前言 现在的游戏制作一般是easyx&#xff0c;有没有直接只用mfc框架的&#xff0c;笔者研究了一番&#xff0c;做出了一个雏形&#xff0c;下面把遇到的问题总结出来 一、MFC框架制作游戏 初步设想&#xff0c;MFC可以选用 对话框 或者 单文档 结构&…

12:遨博机器人SDK二次开发

一、流程步骤 1.获取当前点关节坐标 2.走当前点关节坐标 1.获取目标点x,y,z&#xff08;位置坐标&#xff0c;以m为单位&#xff0c;需要*1000变成mm&#xff09;和四元素&#xff08;位姿坐标&#xff09; 2.四元素→欧拉角&#xff08;弧度制&#xff09; 3.欧拉角&#x…

XPlifeapp:高效打印,便捷生活

在数字化时代&#xff0c;虽然电子设备的使用越来越普遍&#xff0c;但打印的需求依然存在。无论是学生需要打印课表、资料&#xff0c;还是职场人士需要打印名片、报告&#xff0c;一个高效便捷的打印软件都能大大提高工作效率。XPlifeapp就是这样一款超级好用的手机打印软件&…

DeepSeekMath:突破开放式语言模型中数学推理能力的极限

摘要 由于数学推理具有复杂且结构化的特性&#xff0c;这对语言模型构成了重大挑战。在本文中&#xff0c;我们介绍了 DeepSeekMath 7B 模型&#xff0c;该模型在 DeepSeek-Coder-Base-v1.5 7B 模型的基础上&#xff0c;使用从 Common Crawl 获取的 1200 亿个与数学相关的标记…

OpenBayes 教程上新丨谷歌发布 MedGemma,基于 Gemma 3 构建,专攻医学文本与图像理解

在 Google I/O 2025 大会上&#xff0c;公司 CEO Sundar Pichai 在活动首日的主题演讲中便分享了多项创新&#xff0c;例如 Gemini 2.5 的全系列升级&#xff0c;Agent Mode 上线 Chrome&#xff0c;编码智能体 Jules 开启公测&#xff0c;Android XR 正式版亮相等等。而在一众…

【数据结构】栈和队列(下)

目录 一、队列&#xff08;先进先出的特殊结构&#xff09; 队列的概念与结构 二、代码实现 1、定义队列的结构 2、队列的初始化操作 3、判空操作 4、入队操作 5、出队操作 6、取队头、队尾操作 7、队列销毁操作 8、队列中有效数据个数 9、测试代码 10、.h文件 一…

基于卫星遥感数据识别互花米草及原生植被分布及生长的技术原理、关键方法

通过卫星遥感监测生态保护红线&#xff0c;基于卫星遥感数据识别互花米草及原生植被&#xff08;如芦苇&#xff09;的分布、面积及生长状况&#xff0c;主要利用不同植被类型的光谱特征差异、物候周期差异和遥感影像处理技术实现。 上星图地球开放平台获取更多生态保护解决方案…