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

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 

失败:返回错误码


http://www.xdnf.cn/news/381583.html

相关文章:

  • 《Python星球日记》 第52天:反向传播与优化器
  • MySQL 数据类型全面指南:从理论到实践
  • HCIP笔记
  • Veins同时打开SUMO和OMNeT++的GUI界面
  • 基于Arduino Nano的DIY示波器
  • 2505d,d的借用检查器
  • 基于Spring Boot + Vue的母婴商城系统( 前后端分离)
  • InnoDB结构与表空间文件页的详解
  • 前端性能优化
  • Pycharm(二十)张量的运算与操作
  • Webug4.0靶场通关笔记-靶场搭建方法(3种方法)
  • Kubernetes生产实战(十三):灰度发布与蓝绿发布实战指南
  • 关于流媒体的知识总结
  • 全息美AISEO引领未来智能营销新趋势
  • SRP单一职责原则
  • 备战菊厂笔试3
  • short变量赋值为32768, 实际为什么是-32768?不同语言的不同进制字面量?字面量?编程语言的基本类型?
  • Java、Python、NodeJS等开发环境安装及配置镜像加速到国内源
  • .Net HttpClient 使用准则
  • 【脑机接口临床】脑机接口手术的风险?脑机接口手术的应用场景?脑机接口手术如何实现偏瘫康复?
  • RT-Thread 深入系列 Part 6:高性能与低功耗优化策略
  • 智能库室联管联控系统|智能兵器室门禁管理系统
  • AI日报 · 2025年5月10日|OpenAI“Stargate”超级数据中心项目掀起美国各州争夺战
  • Dify+Ollama+Deepseek+BGE-M3来搭建本地知识库实操
  • C++ Vector深度易错点指南(临时抱佛脚)(基础用法;进阶;高级;实战)
  • PyTorch API 1 - 概述、数学运算、nn、实用工具、函数、张量
  • 【LangChain全景指南】构建下一代AI应用的开发框架
  • 数字相机的快门结构
  • not a genuine st device abort connection的问题
  • 实现三个采集板数据传送到一个显示屏的方案