Linux:线程同步与互斥
目录
线程互斥
锁
初始化
销毁
加锁
解锁
线程同步
条件变量
初始化
销毁
等待条件满足
唤醒等待
pthread_cond_signal
pthread_cond_broadcast
生产者消费者模型
3种关系
2种角色
1个交易场所
POSIX信号量
初始化
销毁
等待
发布
线程互斥
互斥相关概念
临界资源:多线程执行流共享的资源就叫做临界资源。
临界区:每个线程内部,访问临界资源的代码,就叫做临界区。
互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用。
原子性:不会被任何调度机制打断的操作,该操作只有两态,要么完成,要么未完成。
多线程并发操作一些共享变量会有一些问题
例如变量++,--的操作就不能多线程并发访问
++,--的操作在汇编中需要分为3步
1.将变量从内存加载到寄存器中
2.更新寄存器里面的值,执行+1(-1)操作
3.将新值从寄存器写回会变量的内存地址中
因为寄存器用的都是同一个,在并发访问时就会出现问题
要解决以上问题,需要做到三点:
1.代码必须要有互斥行为:当代码进入临界区执行时,不允许其他线程进入该临界区。
2.如果多个线程同时要求执行临界区的代码,并且临界区没有线程在执行,那么只能允许一个线程进入该临界区。
3.如果线程不在临界区中执行,那么该线程不能阻止其他线程进入临界区。
想要做到这三点,我们可以使用一把锁。Linux上提供的这把锁叫互斥量
锁
pthread_mutex_t
这是一个互斥锁的类型,定义在POSIX线程库中。
互斥锁用于保护共享资源的访问,确保在多线程环境中,同一时间只有一个线程可以访问该资源,从而避免数据竞争和不一致的问题。
我们可以用这个类型来定义一个锁变量,并初始化它
初始化
方法1:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
PTHREAD_MUTEX_INITIALIZER这是一个宏,用于初始化静态分配的互斥锁
方法2:
#include <pthread.h>int pthread_mutex_init(pthread_mutex_t *mutex,
const pthread_mutexattr_t *mutexattr);
mutex:指向要初始化的互斥锁对象的指针
mutexattr:指向互斥锁属性对象的指针。如果为NULL,则使用默认属性(一般情况使用NULL即可)
返回值:
成功:返回0
失败:返回错误码
销毁
锁也需要像malloc,new出来的动态内存一样需要我们手动释放,但并不是所有情况都需要手动释放的
当使用PTHREAD_MUTEX_INITIALIZER初始化的互斥量不需要销毁
#include <pthread.h>int pthread_mutex_destroy(pthread_mutex_t *mutex);
mutex:指向要销毁的互斥锁对象的指针
返回值:
成功:返回0
失败:返回错误码
加锁
我们可以对一段代码区进行加锁,这样就只能有单执行流访问一段代码了
#include <pthread.h>int pthread_mutex_lock(pthread_mutex_t *mutex);
pthread_mutex_lock用于锁定一个互斥锁
mutex:指向要锁定的互斥锁对象的指针
返回值:
成功:返回0
失败:返回错误码
解锁
有加锁当然也会有解锁,加锁和解锁之间的区域就是我们拥有锁的区域
#include <pthread.h>int pthread_mutex_unlock(pthread_mutex_t *mutex);
pthread_mutex_unlock用于解锁一个互斥锁
mutex:指向要解锁的互斥锁对象的指针
返回值:
成功:返回0
失败:返回错误码
线程同步
条件变量
条件变量是一种在多线程编程中用于线程同步的机制,它允许线程在某些条件不满足时进入等待状态,直到条件满足时才被唤醒继续执行。
初始化
初始化一个条件变量。
int pthread_cond_init(pthread_cond_t *cond
, const pthread_condattr_t *cond_attr);
cond:指向条件变量的指针,需要初始化的条件变量。
cond_attr: 指向条件变量属性的指针。如果为NULL,则使用默认属性。
返回值:
成功:返回0
失败:返回错误码
销毁
销毁一个条件变量,释放相关资源。
int pthread_cond_destroy(pthread_cond_t *cond);
cond:指向条件变量的指针,需要销毁的条件变量。
返回值:
成功:返回0
失败:返回错误码
等待条件满足
使线程进入等待状态,直到条件变量被通知。
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
cond:指向条件变量的指针。
mutex:指向互斥锁的指针,该互斥锁必须已经被当前线程锁定。
当调用pthread_cond_wait的时候,线程会释放mutex,并进入等待状态
当条件变量被通知时,线程会被唤醒,并重新尝试获取mutex
唤醒等待
pthread_cond_signal
通知一个等待条件变量的线程。
int pthread_cond_signal(pthread_cond_t *cond);
cond:指向条件变量的指针。
返回值:
成功:返回0
失败:返回错误码
pthread_cond_broadcast
通知所有等待条件变量的线程。
int pthread_cond_broadcast(pthread_cond_t *cond);
cond:指向条件变量的指针。
返回值:
成功:返回0
失败:返回错误码
生产者消费者模型
3种关系
生产者之间:竞争关系,互斥关系
消费者之间:竞争关系,互斥关系
生产者和消费者之间:竞争关系,互斥关系,同步关系
2种角色
生产者角色和消费者角色
1个交易场所
以特定结构构成的内存空间
POSIX信号量
初始化
初始化一个信号量。
#include <semaphore.h>int sem_init(sem_t *sem, int pshared, unsigned int value);
sem:指向信号量的指针。
pshared:指定信号量是否可以在不同进程之间共享。为0:信号量仅在当前进程内的线程之间共享。非0:信号量可以在不同进程之间共享(需要映射到共享内存)
value:信号量的初始值。
返回值:
成功:返回0
失败:返回错误码
销毁
销毁一个信号量,释放相关资源。
#include <semaphore.h>int sem_destroy(sem_t *sem);
sem:指向信号量的指针。
返回值:
成功:返回0
失败:返回错误码
等待
使线程进入等待状态,直到信号量的值大于零,然后将信号量的值减一。
#include <semaphore.h>int sem_wait(sem_t *sem);
sem:指向信号量的指针。
返回值:
成功:返回0
失败:返回错误码
发布
将信号量的值加一,通知等待信号量的线程。
#include <semaphore.h>int sem_post(sem_t *sem);
sem:指向信号量的指针。
返回值:
成功:返回0
失败:返回错误码
完
相关文章:

Linux:线程同步与互斥
目录 线程互斥 锁 初始化 销毁 加锁 解锁 线程同步 条件变量 初始化 销毁 等待条件满足 唤醒等待 pthread_cond_signal pthread_cond_broadcast 生产者消费者模型 3种关系 2种角色 1个交易场所 POSIX信号量 初始化 销毁 等待 发布 线程互斥 互斥相关…...

每天五分钟机器学习:拉格朗日对偶函数
本文重点 在数学优化领域,拉格朗日对偶函数作为连接原始约束问题与对偶问题的核心纽带,展现了将复杂约束优化转化为无约束优化的方式。 数学表达 原始问题建模 拉格朗日函数构造 此时的目标就是: 先假设w为常数,让拉格朗日函数对橙子变量λ求极大值,消掉λ之后,在对λ求…...

AutoGen 框架解析:微软开源的多人 Agent 协作新范式
一、引言 在大语言模型(LLM)快速发展的今天,复杂任务的自动化协作需求日益增长。微软开源的AutoGen 框架(GitHub Star 超 10 万)提供了一种基于多智能体对话的协作范式,通过自然语言交互实现多角色 Agent …...

【bibtex4word】在Word中高效转换bib参考文献,Texlive环境安装bibtex4word插件
前言 现已退出科研界,本人水货一个。希望帮到有缘人 本篇关于如何将latex环境中的参考文献bib文件转化为word,和一些踩坑记录。 可以看下面的资料进行配置,后面的文字是这些资料的补充说明。 参考文章:https://blog.csdn.net/g…...
Listremove数据时报错:Caused by: java.lang.UnsupportedOperationException
看了二哥的foreach陷阱后,自己也遇见了需要循环删除元素的情况,立马想到了当时自己阴差阳错的避开所有坑的解决方式:先倒序遍历,再删除。之前好使,但是这次不好使了,报错Caused by: java.lang.UnsupportedO…...
k8s node 报IPVS no destination available
在 Kubernetes 集群中,IPVS no destination available 错误通常表示 kube-proxy(IPVS 模式)无法为 Service 找到可用的后端 Pod。这会导致流量无法正确转发,影响服务可用性。以下是详细的排查和解决方法: 一、错误原因…...

单片机-STM32部分:10-2、逻辑分析仪
飞书文档https://x509p6c8to.feishu.cn/wiki/VrdkwVzOnifH8xktu3Bcuc4Enie 安装包如下:根据自己的系统选择,目前这个工具只有window版本哦 安装方法比较简单,都按默认下一步即可,注意不要安装到中文路径哦。 其余部分参考飞书文档…...

计算机网络基础科普
IP地址是计算机网络中标识设备的唯一地址 IPv4(32位)IPv6(128位) 1.IPv4(32位) 简介:IPv4(Internet Protocol version 4)是互联网协议(IP)的…...

阿里云CDN的源站配置:权重的详解
在阿里云CDN中为静态资源域名cdn.example.com配置源站时,权重设置需根据实际架构和目标灵活调整。以下是具体建议和配置步骤: 一、权重的核心作用 在阿里云CDN中,源站权重用于控制多个源站之间的流量分配比例,适用于以下场景&…...
《Python星球日记》 第37天:向量与矩阵进阶
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏:《Python星球日记》,限时特价订阅中ing 目录 一、特征值与特征向量1. 基本概念2. 如何找到特征值和特征向量3. 特征值和特征向量的几何意义二…...

虚幻引擎5-Unreal Engine笔记之显卡环境设置使开发流畅
虚幻引擎5-Unreal Engine笔记之显卡环境设置使开发流畅 code review! 文章目录 虚幻引擎5-Unreal Engine笔记之显卡环境设置使开发流畅1.电源管理2.显卡优先设置3.拯救者支持FnQ性能模式切换,建议开发前切至“野兽模式”或高性能模式。4.NVIDIA 驱动设置5.VS2022中…...

【Linux】冯诺依曼体系结构和操作系统的理解
目录 冯诺依曼体系结构一个例子来深入理解 初识操作系统操作系统的作用设计操作系统的目的操作系统之上和之下分别有啥 管理的精髓,先描述,再组织 冯诺依曼体系结构 我们知道,计算机这个东西发明出来就是帮助人们快速解决问题的。那如果我们想…...
如何构建容器镜像并将其推送到极狐GitLab容器镜像库?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 构建容器镜像并将其推送到容器镜像库 (BASIC ALL) 在构建和推送容器镜像之前,您必须通过容器镜像库的身份验证。 …...

计网学习笔记———网络
🌿网络是泛化的概念 网络是泛化的概念 🍂泛化理解 网络的概念在生活中无处不在举例:社交网络、电话网路、电网、计算机网络 🌿网络的定义 定义: 离散的个体通过通讯手段连成群体,实现资源的共享与交流、个…...
计算机三大主流操作系统的前世今生 - Linux|macOS|Windows
全文目录 1 引言2 起源之路2.1 Linux 起源2.2 macOS 起源2.3 Windows 起源 3 综合解析3.1 Linux系统综合解析3.1.1 系统定义与核心架构3.1.2 发展历程3.1.3 核心特点3.1.4 主流发行版3.1.5 应用场景 3.2 macOS系统综合解析3.2.1 系统定义与核心架构3.2.2 发展历程3.2.3 核心特点…...

数据集-目标检测系列- 烟雾 检测数据集 smoke >> DataBall
数据集-目标检测系列- 消防 浓烟 检测数据集 smoke>> DataBall 数据集-目标检测系列- 烟雾 检测数据集 smoke >> DataBall * 相关项目 1)数据集可视化项目:gitcode: https://gitcode.com/DataBall/DataBall-detections-10…...

【单片机毕业设计15-基于stm32c8t6的智能酒窖系统设计】
【单片机毕业设计15-基于stm32c8t6的智能酒窖系统设计】 前言一、功能介绍二、硬件部分三、软件部分总结 前言 🔥这里是小殷学长,单片机毕业设计篇15-基于stm32c8t6的智能酒窖系统设计 🧿创作不易,拒绝白嫖可私 一、功能介绍 ----…...

【Bluedroid】蓝牙 HID 设备服务注册流程源码解析:从初始化到 SDP 记录构建
本文围绕蓝牙 HID(人机接口设备)服务注册流程,详细解析从 HID 服务启用、设备初始化、L2CAP 通道注册到 SDP(服务发现协议)记录构建的全流程。通过分析关键函数如btif_hd_service_registration、BTA_HdEnable、HID_Dev…...

TWAS、GWAS、FUSION
全基因组关联研究(GWAS,Genome-Wide Association Study)是一种统计学方法,用于在全基因组水平上识别与特定性状或疾病相关的遗传变异。虽然GWAS可以识别与性状相关的遗传信号,但它并不直接揭示这些遗传变异如何影响生物…...

测试一下多模态提取图片中文字的能力
测试一下多模态提取图片中文字的能力 原图片, 提取结果, 各位嘉宾,大家好!明天(5月11日)9:00-12:00将在大连市高新园区星火亚庭32号A座一层二楼设置咖啡厅等六个小水活动。请大家积极安排时间,…...

(51单片机)LCD显示红外遥控相关数字(Delay延时函数)(LCD1602教程)(Int0和Timer0外部中断教程)(IR红外遥控模块教程)
前言: 本次Timer0模块改装了一下,注意!!!今天只是简单的实现一下,明天用次功能显示遥控密码锁 演示视频: 在审核 源代码: 如上图将9个文放在Keli5 中即可,然后烧录在…...

物品识别 树莓派4 YOLO v11
让树莓派可以识别身边的一些物品 python3 -m venv --system-site-packages yolooo source yolooo/bin/activate 树莓派换清华源,bookworm 下面这条命令将安装 OpenCV 以及运行 YOLO 所需的基础设施 pip install ultralytics 还会安装大量其他软件包,…...

【计算机视觉】3DDFA_V2中表情与姿态解耦及多任务平衡机制深度解析
3DDFA_V2中表情与姿态解耦及多任务平衡机制深度解析 1. 表情与姿态解耦的技术实现1.1 参数化建模基础1.2 解耦的核心机制1.2.1 基向量正交化设计1.2.2 网络架构设计1.2.3 损失函数设计 1.3 实现代码解析 2. 多任务联合学习的权重平衡2.1 任务定义与损失函数2.2 动态权重平衡策略…...

istio in action之流量控制与路由
当流量进入集群后,我们如何确保它能被精确地路由到正确的服务?特别是当我们需要发布新版本时,如何在不中断服务的前提下,安全地将用户引入到新版本?这正是我们今天要深入探讨的精细化流量控制,看看 Istio 如…...
图像处理篇---opencv实现坐姿检测
文章目录 前言一、方法概述使用OpenCV和MediaPipe关键点检测角度计算姿态评估 二、完整代码实现三、代码说明PostureDetector类find_pose()get_landmarks()cakculate_angle()evaluate_posture() 坐姿评估标准(可进行参数调整):可视化功能&…...

优选算法——前缀和
目录 1. 数组的中心下标 2. 除自身以外数组的乘积 3. 和为k的子数组 4. 和可被K整除的子数组 5. 连续数组 6. 矩阵区域和 1. 数组的中心下标 题目链接:724. 寻找数组的中心下标 - 力扣(LeetCode) 题目展示: 题目分析&am…...

用AI写简历是否可行?
让AI批量写简历然后投简历是绝对不行的!!! 为什么不行,按照 "招聘经理" 工作经历举例: ai提示词:请帮我写一份招聘经理的工作经历内容: 招聘经理 | XXX科技有限公司 | 2020年…...

力扣题解:2、两数相加
个人认为,该题目可以看作合并两个链表的变种题,本题与21题不同的是,再处理两个结点时,对比的不是两者的大小,而是两者和是否大于10,加法计算中大于10要进位,所以我们需要声明一个用来标记是否进…...
C语言_函数hook方案
背景 单体测试中测试一个函数时,该函数调用的其他函数,需要按照测试case,依赖其他函数进行调用参数检查,返回特定值。但是其他函数,不容易做到参数检查和返回特定值,这时需要将其他函数进行hook,hook函数用户自己实现,比较容易实现参数检查和返回值特定值。 本文主要…...

IPM IMI111T-026H 高效风扇控制板
概述: REF-MHA50WIMI111T 是一款专为风扇驱动设计的参考开发板,搭载了英飞凌的IMI111T-026H iMOTION™智能功率模块(IPM)。这个模块集成了运动控制引擎(MCE)、三相栅极驱动器和基于IGBT的功率级,全部封装在一个紧凑的DSO22封装中。REF-MHA50…...