【Linux系统】信号量实现同步和互斥

一.回顾

在这之前已经讲解了System V版本的信号量,主要内容为以下3点:

  1. 信号量本质是一把计数器
  2. 申请信号量本质就是预订资源
  3. PV操作(申请和释放)是原子的

今天我们要学习的是POSIX版本的信号量,以上三点同样遵循

二.信号量VS互斥锁

1.联系:

信号量和互斥锁都是保护公共资源的手段,想要通过临界区访问临界资源,必须先要申请信号量或者互斥锁。并且计数器为1的信号量功能等同于互斥锁。

2.区别:

  1. 互斥锁将公共资源当成一个整体使用,信号量可以实现把公共资源分成若干区域,给不同的执行流同时使用。
  2. 申请锁成功,线程进来后一般还要使用如if这样的判断语句,来检测资源是否就绪,如果没有就绪,为了并发的高效,还需要等待条件变量。(进电影院之后再现场买票)。但是申请信号量成功,线程进来之后无需判断资源是否就绪,因为只要申请信号量成功,说明一定有资源分配给你,并且这份资源只有你自己能访问。(提前买电影票)
  3. 互斥锁在信号量都在pthread库中,不过互斥锁声明在<pthread.h>头文件,信号量声明在<semaphore.h>中

线程使用信号量流程:

申请信号量->访问指定区域->释放信号量

三.信号量用法

1.初始化信号量

sem是定义的信号量。pshared指定信号量是否进程共享,为0则线程共享,非0则进程共享。value则是计数器的初始值,表示想把公共资源分成多少份使用

2.申请信号量(P操作)

3.释放信号量(V操作)

4.销毁信号量

四.基于环形队列的生产者消费者模型

1.生产消费过程

生产者和消费者在环形队列的生产消费过程:

  1. 生产者不能把消费者套一个圈
  2. 消费者不能超过生产者
  3. 生产者和消费者只有两种场景会指向同一个位置:队列为空和为满

只要生产者和消费者不指向同一个位置,就可以多线程并发访问环形队列。如果为空,只能让生产者跑,如果为空,只能让消费者先跑。"只能"表现出的是互斥,"先"表现出的是同步。所以基于环形队列的生产者消费者模型,也有同步和互斥,但这种同步和互斥是局部性的,只有队列为空为满时才需要维持,这样就实现了生产和消费的并发。

2.信号量设计

生产者认为空间是资源,消费者认为数据是资源,所以分别为生产者和消费者设计条件变量,来表示空间和数据的数量。

初始时,生产者的信号量是n,消费者的信号量是0。
伪代码:

//1.初始化

p->sem_space = N;

c->sem_data = 0;

//2.生产者

P(sem_space)

//生产行为,位置待定

V(sem_data)

//3.消费者

P(sem_data)

//消费行为,位置待定

V(sem_space)

3.多生产和多消费

以上的两个信号量可以保证生产者和消费者之间的同步和互斥。如果是多个生产者和消费者,信号量能否保证生产者之间,消费者之间的互斥关系呢?

不能!因为生产者共用同一个_p_step,消费者共用同一个_c_step,读写位置的安全无法保证,也就不能保证多线程访问的是不同的位置,所以需要设计两个锁,分别对_p_step和_c_step进行保护。

相关推荐
星夜离尘56几秒前
MATLAB 工程实验:不等间隔流量积分,先把缺口与覆盖率说清楚
开发语言·matlab·时间戳·数据质量·数值积分
Ai-_Man24 分钟前
Meta Muse还是不可以导出左侧所有对话,只能点进去单条内容导出,方法不对吗?
开发语言·人工智能·ai·小程序·c#·1024程序员节
梓豪csd27 分钟前
消息订阅中心:谁该收到哪条通知
java·开发语言·人工智能·低代码·自动化·1024程序员节
王中阳Go32 分钟前
两个入口答案不一致先别调模型:6 行入口口径对账表(附脚本)
人工智能·后端·python·大语言模型·1024程序员节
by209991 小时前
Linux 基础指令与文件操作
linux·1024程序员节
会编程的小孩1 小时前
C++ qt的安装
c++
学逆向的1 小时前
C 枚举变量
c语言·开发语言·网络安全
2401_868534781 小时前
软考网络规划设计师SSL协议知识点详解
服务器·网络
Sakura_j_h_1 小时前
Python 在定时任务里输出 emoji,UnicodeEncodeError 从哪来
开发语言·字符编码·windows·python·定时任务
Escalating_xu1 小时前
【Linux 网络编程】手写序列化与反序列化:从 x op y 到能校验的文本协议
linux·运维·网络