1 图书馆阅览室问题
问题描述:假定阅览室最多可同时容纳100个人阅读,读者进入时,必须在阅览室门口的一个登记表上登记,内容包括姓名、座号等,离开时要撤掉登记内容。用P、V操作描述读者进程的同步算法。
(分析:读者有任意多个,但进入阅览室阅读最多为100人,为此可设一个信号量s,代表空座位的数目;另登记表为临界资源,需设一个用于互斥的信号量mutex,防止2个及以上的读者进程同时对此表访问。对于每个读者的动作包括进入、阅读、离开。)
struct semaphore s,mutex=100, 1;
cobegin
void readeri(void)(i=1,2,...,k)
{while(TRUE){
P(s);
P(mutex);
查登记表,置某座位为占用;
V(mutex);
......
reading;
......
P(mutex);
查登记表,置某座位为空;
V(mutex);
V(s);}
}
coend
2吃水果问题
问题描述:桌上有一只盘子,每次只能放一个水果,爸爸专向盘中放苹果,妈妈专向盘中放桔子,儿子专等吃盘里的桔子,女儿专等吃盘里的苹果。只要盘子空,则爸爸或妈妈可向盘中放水果,仅当盘中有自己需要的水果时,儿子或女儿可从中取出,请给出四人之间的同步关系,并用PV操作实现四人正确活动的程序。
解:四人之间的关系:
1爸爸,妈妈要互斥使用盘子,所以两者之间是互斥关系;
2爸爸放的苹果,女儿吃,所以两者是同步关系;
3妈妈放的桔子,儿子吃,所以两者也是同步关系。
struct semaphores,sp,so=1,0,0;
cobegin
void father(void)
{
while(TRUE){
have an apple;
P(s);
put an apple;
V(sp);}
}
void mother(void)
{
while(TRUE){
have an orange;
P(s);
put an orange;
V(so);}
}
void son(void)
{
while(TRUE){
P(sp);
get an orange;
V(s);
eat an orange;}
}
void daught(void)
{
while(TRUE){
P(sp);
get an apple;
V(s);
eat an apple;}
}
coend
3司机-售票员问题
设公共汽车上,司机和售票员的活动分别是:
司机:启动车辆;正常行车;到站停车
售票员:上下乘客;关车门;售票;开车门;上下乘客
在汽车不断到站,停车,行驶过程中,这两个活动的同步关系?
No 1:
struct semaphore s1,s2=0,0;
cobegin
void driver(void)
{
while(TRUE){
p(s2);
启动车辆;
正常行车;
到站停车;
V(s1);}
}
void conductor(void)
{
while(TRUE){
上、下乘客;
关车门;
V(s2);
售票;
P(s1);
开车门;
上、下乘客;}
}
coend
No 2:
struct semaphore s1,s2=0,0;
cobegin
void driver(void)
{
while(TRUE){
p(s2);
启动车辆;
正常行车;
到站停车;
V(s1);}
}
void conductor(void)
{
while(TRUE){
P(s1);
开车门;
上、下乘客;
关车门;
V(s2);
售票;}
}
coend
4理发师问题
引入3个信号量和一个控制变量:
1)控制变量waiting用来记录等候理发的顾客数,初值均为0;
2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;
3)信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为0;
4)信号量mutex用于互斥,初值为1.
var waiting:integer;/*等候理发的顾客数*/
CHAIRS:integer;/*为顾客准备的椅子数*/
customers,barbers,mutex:semaphore;
customers: =0;barbers: =0;waiting: =0;mutex: =1;
cobegin
Procedure barber;
begin
while(TRUE);/*理完一人,还有顾客吗?*/
P(cutomers);/*若无顾客,理发师睡眠*/
P(mutex);/*进程互斥*/
waiting:=waiting-1;/*等候顾客数少一个*/
V(barbers);/*理发师准备去为一个顾客理发*/
V(mutex);/*开放临界区*/
cut-hair();/*正在理发*/
end;
procedure customer i
begin
P(mutex);/*进程互斥*/
if waiting <CHAIRS
{waiting:=waiting+1;/*等候顾客数加1*/
V(customers);/*必要的话唤醒理发师*/
V(mutex);/*开放临界区*/
P(barbers);/*无理发师,顾客坐着养神*/
get-haircut();/*一个顾客坐下等理发*/
}
else V(mutex);/*人满了,走吧!*/
end;
Coend
[问题分析] 题目中要求描述理发师和顾客的行为,因此需要两类进程Barber 0和Customer0分别描述理发师和顾客的行为。当理发师看报时顾客进来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师看报,因此理发师和顾客之间是同步的关系,由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有n个,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。故引入3个信号量和一个控制变量:1)控制变量waiting用来记录等候理发的顾客数,初值均为0;2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;3)信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为0;4)信号量 mutex用于互斥,初值为1
5.哲学家进餐问题(解决死锁)
(1)最多允许4个哲学家同时拿起筷子
变量设置:N=5;哲学家数
信号量:number=4;用于计数的信号量;
Fork [i] =1;i=0, 1, 2, 3, 4第i个哲学家进程的活动
Cobegin
.
Philosopher[i]:{
While(true)
{
p(number);
P(fork[i]);
P(fork[(i+1) mod N]);
Eating;
v(fork[i]);
v(fork[(i+1) mod N]);
v(number);
thinking
}
}
.
Coend
(2)偶数编号的哲学家先拿左筷子,奇数编号的哲学家先拿右筷子
Philosopher[i]: {
While(true)
{
ifi%2=0
{
P(fork[i]);
P(fork[(i+1) mod N]);
Eating;
v(fork[i]);
v(fork[(i+1) mod N])
}
Else
{
P(fork[(i+1) mod N]);
P(fork[i]);
Eating;
v(fork[(i+1) mod N]);
v(fork[i])
}
Thinking
}
}