[操作系统] - 进程关系之同步互斥
同步与互斥
- 临界区&临界资源
临界资源(Critical Resouce): 一次仅允许一个进程使用的共享资源
临界区(critical section):每个进程中访问临界资源的那段代码
-
临界区进入的准则
- 单个进入
- 独自占用
- 尽快退出
- 落败让权[^6]
-
进程互斥实现方式
-
软件
-
锁机制
缺点:让权等待 🙅♀️🚫🙅♂️
-
信号量机制
整型信号量→ 结构型信号量 → 信号量集- 整型信号量
- 结构型信号量-单信号量
-
结构型信号量-AND信号量
-
信号量集
-
-
硬件
-
关中断
缺点:过于暴力 🤣😓
-
TSL、SWAP指令
缺点:让权等待 🙅♀️🚫🙅♂️ 无法用于复杂问题🙅♂️🚫🙅♀️
-
-
-
经典进程的同步问题
- 生产者—消费者问题
回答:两个P操作不能交换次序,要先对资源信号量(如empty)P操作,再对互斥信号量(mutex)进行操作。否则会死锁
两个V操作可以交换次序
-
哲学家进餐问题
-
读者-写者问题
-
打瞌睡的理发师问题
分析
理发师和每一位顾客各一个进程。
理发师进程分析:理发师开始工作时,先看一下店内有无顾客,如果没有, 就打瞌睡(阻塞);如果有,就被唤醒,进行理发,且等待人数减1。注:理发师由于不停地理发故使用while循环。
顾客进程分析:每一位顾客一个进程,故有多个顾客进程。每个进程中,如果顾客数超过座位数,就结束进程。否则等待理发师。顾客理完发(或无座位)就走,因此不需要while循环。
该问题和生产者-消费者问题相似,但有什么不同?
满座后,顾客离开店不再排队,即不需要PV
/* 引入3 个信号量和一个控制变量: 控制变量waiting 用来记录等候理发的顾客数,初值为0; 信号量customers 用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0; 信号量barbers 用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为0; 信号量mutex 用于互斥,初值为1。 */ #define CHAIRS 5 typedef struct { int value; struct PCB* list; } semaphore; semaphore customers = 0; semaphore barbers = 0; semaphore mutex = 1; int waiting = 0; void barber(void) { while (TRUE) { P(customers); /*如果没有顾客,则理发师打瞌睡*/ P(mutex); /*互斥进入临界区*/ waiting--; V(barbers); /*一个理发师准备理发*/ V(mutex); /*退出临界区*/ cut_hair(); /*理发(在临界区之外)*/ } } void customer(void) { P(mutex); /*互斥进入临界区*/ if (waiting﹤CHAIRS) { waiting++; V(customers); /*若有必要,唤醒理发师*/ V(mutex); /*退出临界区*/ P(barbers); /*如果理发师正忙着,则顾客打瞌睡*/ get_haircut(); } else V(mutex); /*店里人满了,不等了*/ }