Hurry Rechard
Articles8
Tags3
Categories3
信号量相关问题典型案例

信号量相关问题典型案例


此为博主从个人csdn博客搬运来的第三篇,内容关于操作系统中信号量的经典题目。

题干

类读者写者问题

有P1、P2、P3三类进程共享同一表格F,其中P1对F只读不写,P2对F只写不读,P3对F先读后写。不同进程可同时读F,但如果有进程写时,其余进程不能读或写。请用信号量以及P、V操作给出解决方案,并做一定分析。

理发师问题

理发店中有一位理发师,一把理发椅,N个候坐用的凳子。若无顾客,则理发师睡觉,且第一个顾客到来时叫醒理发师;若理发师正理发时有顾客到店,有空凳子就坐下,没有就离开。请用信号量以及P、V操作给出解决方案。

解法

类读者写者问题

简要分析:这是典型的读者写者问题,P1相当于读者,P2为写者,P3则是先读者后写者的角色。(本解答只是其中两种较简单的解法)

作答:

解法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 设置信号量以及相关参数
semaphore w = 1; //用以保持读者写者、写者写者互斥
semaphore mutex = 1; //用以互斥访问count
int count = 0; //用以记录当前读者数

P1(){
while(1) {
P(mutex);
if (count == 0) P(w);
count++;
V(mutex);
reading...
P(mutex);
count--;
if (count == 0) V(w);
V(mutex);
}
}

P2(){
while(1) {
P(w);
writing...
V(w);
}
}

P3(){
while(1) {
P(mutex);
if (count == 0) P(w);
count++;
V(mutex);
reading...
P(mutex);
count--;
if (count == 0) V(w);
V(mutex);
P(w);
writing...
V(w);
}
}

简要分析:此解法满足读者优先的策略,因为一旦有读者进程进入便可抢占插入到写者进程之前。

解法二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 设置信号量以及相关参数
semaphore rw = 1; //用以保持读者写者、写者写者互斥
semaphore w = 1; //用以实现读写公平
semaphore mutex = 1; //用以互斥访问count
int count = 0; //用以记录当前读者数

P1(){
while(1) {
P(w);
P(mutex);
if (count == 0) P(rw);
count++;
V(mutex);
V(w);
reading...
P(mutex);
count--;
if (count == 0) V(rw);
V(mutex);
}
}

P2(){
while(1) {
P(w);
P(rw);
writing...
V(rw);
V(w);
}
}

P3(){
while(1) {
P(mutex);
if (count == 0) P(w);
count++;
V(mutex);
reading...
P(mutex);
if (count == 0) V(w);
count--;
V(mutex);
P(w);
P(rw);
writing...
V(rw);
V(w);
}
}

简要分析:此解法可实现较为公平的读写,因为此解法遵循先来先服务的原则。

理发师问题

对于理发师问题,可设置三个信号量加以解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
semaphore mutex = 1;			//用于互斥访问count
semaphore barber = 0; //可理解为可用的理发师资源(清醒时)
semaphore customer = 0; //可理解为等待理发的顾客
int count = 0; //相当于customer的计数

Barber(){
while(1) {
P(customer); //等候顾客,即睡觉
P(mutex); //有顾客,进入临界区
count--;
V(barber); //可理解为释放一个理发师资源
V(mutex); //退出临界区
理发……
}
}

Customer(){
P(mutex); //有顾客来,进入临界区
if (count < N) { //若有空位置则坐下
count++; //等待顾客数加一
V(customer); //唤醒理发师
V(mutex); //退出临界区
P(barber); //可理解为申请一个理发师资源
理发……
} else { //没位置顾客离开理发店,退出临界区
V(mutex);
}
}
Author:Hurry Rechard
Link:https://hurry-hub.github.io/2021/06/19/PV/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可
×