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

day27 同步互斥

同步互斥

线程资源是共享的,此时会出现多个线程对全局变量的访问,导致数据错误,以此引入同步互斥

临界资源:多个线程抢夺的资源(全局变量,文件,数据库,内核资源)

临界区:访问临界资源的代码

互斥:同一时间内只允许一个线程访问临界资源(共享资源)

同步:在互斥的基础上保证访问者的顺序

解决同步互斥问题:互斥锁,信号量,条件变量

互斥锁

概念

对于要访问临界资源的线程做上锁操作,如果上锁成功,则访问成功,如果上锁失败,则阻塞并等待互斥锁解锁再解除阻塞,再执行

速记

函数功能参数返回值
pthread_mutex_init初始化&mutex,        NULL永0
pthread_mutex_lock上锁&mutex 成功0,失败非0
pthread_mutex_unlock解锁&mutex 成功0,失败非0
pthread_mutext_destroy销毁锁&mutex 成功0,失败非0
pthread_mutex_trylock尝试上锁&mutex 成功0,失败非0

相关函数

pthread_mutex_init

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

功能:初始化进程锁

定义方式:推荐第二个,我懒  ,可定义为全局

                   1.int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

                   2.pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;

参数:pthread_mutex_t *mutex        指向内存中mutex锁的地址的指针

           const pthread_mutexattr_t *mutexattr       互斥锁属性 快速(默认),递归,错误检错锁

                                                                              默认NULL

返回值:永为0 

pthread_mutex_lock

int pthread_mutex_lock(pthread_mutex_t *mutex);

功能:上锁,如果锁资源被占用,阻塞等待,直到锁资源被释放解除阻塞上锁成功

参数: pthread_mutex_t *mutex        指向内存中mutex锁的地址的指针

返回值:成功返回0,失败返回非0

pthread_mutex_unlock

int pthread_mutex_unlock(pthread_mutex_t *mutex);

功能:解锁,释放锁资源

参数: pthread_mutex_t *mutex        指向内存中mutex锁的地址的指针

返回值:成功返回0,失败返回非0

pthread_mutext_destroy

int pthread_mutex_destroy(pthread_mutex_t *mutex);

功能:销毁锁资源

参数: pthread_mutex_t *mutex        指向内存中mutex锁的地址的指针

返回值:成功返回0,失败返回非0

pthread_mutex_trylock

int pthread_mutex_trylock(pthread_mutex_t *mutex);

功能:尝试上锁,锁资源被占用了不会阻塞,报错EBUSY

参数: pthread_mutex_t *mutex        指向内存中mutex锁的地址的指针

返回值:成功返回0,失败返回非0

死锁

1.重复上同一把锁

2.锁资源没有释放,线程异常退出

3.线程重复上多把锁

信号量

对于要访问临界资源的线程都做申请信号的操作

信号量大于0申请成功,信号量-1  释放成功,信号量+1
等于0申请失败,处于阻塞态,直到信号量大于0,解除阻塞

互斥锁:称为二值信号量(0,1)

解决问题:一个生产者少量消费者

P操作:申请  信号量-1

V操作:释放  信号量+1

速记

#include <semaphore.h>

函数功能参数返回值
sem_init初始化&sem,0,value成功返回0,失败返回-1,更新errno
sem_wait 申请P&sem同上
sem_post释放V&sem同上
sem_destroy销毁&sem同上
sem_getvalue获取信号量&sem,&sval同上

Link with -pthread.

相关函数

sem_init

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

功能:初始化的信号量

参数: sem_t *sem:该指针指向的内存中存储信号量

            int pshared: 0:表示线程共享 非0:表示进程共享

            unsigned int value:用于信号量的初始化,允许多少个线程同时访问临界资源

返回值: 成功返回0,失败返回-1,跟新errno

sem_wait 申请 P -1

int sem_wait(sem_t *sem);

功能:申请信号量 -1  大于0,成功,等于0阻塞,直到大于0解除

参数: sem_t *sem:该指针指向的内存中存储信号量

返回值: 成功返回-,失败返回-1,根新errno

sem_post 释放 V +1

int sem_post(sem_t *sem);

功能:释放信号量 +1 

参数: sem_t *sem:该指针指向的内存中存储信号量

返回值: 成功返回-,失败返回-1,根新errno

sem_destroy

int sem_destroy(sem_t *sem);

功能:销毁信号量

参数: sem_t *sem:该指针指向的内存中存储信号量

返回值: 成功返回-,失败返回-1,根新errno

sem_getvalue

int sem_getvalue(sem_t *sem, int *sval);

功能:获取信号量的值

参数: sem_t *sem:该指针指向的内存中存储信号量

            int *sval:         该指针指向的内存中存储信号量的值

返回值: 成功返回-,失败返回-1,根新errno

条件变量

对于不访问临界资源的线程休眠,并设置一个唤醒条件(条件变量),如果该线程需要访问临界资源时,需要通过其他线程唤醒该线程

速记

函数功能参数返回值
pthread_cond_init初始化&cond,NULL0,非0
pthread_cond_wait进程塞入等待队列&cond,&mutex同上
pthread_cond_siganl唤醒队列第一个&cond同上
pthread_cond_broadcast唤醒整个队列&cond同上
pthread_cond_destroy销毁&cond同上

相关函数

pthread_cond_init

int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);

功能:初始化条件变量

定义方式:推荐第二个,我懒  ,可定义为全局

                   1.int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);

                   2.pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

参数:        pthread_cond_t *cond:该指针指向的内存中存储条件变量

                   pthread_condattr_t *cond_attr:条件变量属性

                                                                      NULL:默认属性

返回值:成功0,失败非0

pthread_cond_wait

int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);

使用流程:

1.上锁pthread_muext_lock()

2.解锁,休眠 pthread_cond_wait()//解锁,休眠 ,上锁(如果被其他线程唤醒后 重新尝试上锁,如果上锁成功,则唤醒成功 如果上锁失败,则唤醒失败)

3.运行

4.解锁

参数: pthread_cond_t *cond:该指针指向的内存中存储条件变量

            pthread_mutex_t *mutex:互斥锁

返回值:成功返回0,失败返回非0

-------------------------------------------

条件变量为什么使用互斥锁:

当多核CPU时,同一时间执行多个线程,且同时调用pthread_cond_wait函数,同时把多个线程存到 休眠队列中,此时这个休眠队列就是多个线程需要抢夺的临界资源,解决互斥问题,需要引入互斥锁 哪个县城抢夺到了互斥锁,就把哪个县城存到休眠队列中,存储以后解锁,其他线程在存储袋休眠队列即可

pthread_cond_siganl

int pthread_cond_signal(pthread_cond_t *cond);

功能:唤醒休眠队列的第一个线程

参数: pthread_cond_t *cond:该指针指向的内存中存储条件变量

返回值:成功返回0,失败返回非0

pthread_cond_broadcast

int pthread_cond_broadcast(pthread_cond_t *cond);

功能:唤醒所有休眠队列的线程

参数: pthread_cond_t *cond:该指针指向的内存中存储条件变量

返回值:成功返回0,失败返回非0

pthread_cond_destroy

int pthread_cond_destroy(pthread_cond_t *cond);

功能:销毁条件变量

参数: pthread_cond_t *cond:该指针指向的内存中存储条件变量

返回值:成功返回0,失败返回非0

http://www.lryc.cn/news/613214.html

相关文章:

  • IDEA-Research推出的一系列检测、分割模型:从DINO(改进版DETR)、Grounding Dino、DINO-X到Grounded SAM2
  • 【SPIE出版| 前4届均已完成EI检索】第五届算法、高性能计算与人工智能国际学术会议(AHPCAI 2025)
  • 解决GitHub push失败-Failed to connect to github.com port 443: Timed out
  • YooAsset为什么要分组
  • 《深入Java包装类体系:类型转换原理与Integer缓存实战指南》
  • jetson上使用opencv的gstreamer进行MIPI和USB摄像头的连接以及udp推流
  • PyTorch RNN 名字分类器
  • 解决 npm i node-sass@4.12.0 安装失败异常 npm i node-sass异常解决
  • QT的拖拽功能
  • vue-plugin-hiprint 打印模版使用
  • DicomObjects COM 8.XX
  • 云平台运维工具 ——AWS 原生工具
  • 008 前端vue
  • 解决React白板应用中的画布内容丢失问题
  • [盛最多水的容器]
  • 【关于Java中==和equals( )和hashCode( )三者异同】
  • Java中接口与抽象类
  • 国内使用 npm 时配置镜像源
  • 2025年 IT 服务管理(ITSM)工具市场分析:选型逻辑与企业适配趋势报告
  • Spring Cloud系列—LoadBalance负载均衡
  • 边缘算力×AI应用:如何在2025年实现爆发式增长
  • 酉矩阵(Unitary Matrix)和随机矩阵
  • “认知裂缝边缘”地带
  • PyTorch LSTM文本生成
  • 基于深度学习的污水新冠RNA测序数据分析系统
  • 进程Linux
  • TSMaster-C小程序使用
  • 深度学习之opencv篇
  • change和watch
  • GPT-5 将在周五凌晨1点正式发布,王炸模型将免费使用??