用信号量进程同步与互斥
1、理解生产者和消费者问题
没有引入信号量时的生产者和消费者进程,什么情况下会出现结果不唯一?
什么情况下会出现永远等待?用信号解决生产者和消费者的同步与互斥,要求能自己写出来。
结果不唯一:假如当前的产品数为8,如果生产者生产一件产品投入缓存区,拟执行产品数加一操作;同时消费者取走一样产品,拟执行产品数减一操作;假如两者交替执行加一或减一操作,取决于其执行速度,产品数为9或7,但正确为8.
永远等待:假如消费者读取产品数为0时,调度程序暂停消费者进程,让生产者进程运行,生产者加入一个产品,将产品数加一,它便调用wakeup()函数来唤醒消费者;但是消费者未睡眠,则唤醒信号丢失,当消费者下次运行时,因已检测到产品数为0,于是去睡眠,当生产者将缓冲区填满后也去睡眠,这就会造成永远等待。
2、哲学家吃面问题
semaphore fork[5];
for(int i=0; i<5;i++)
fork[i]=1;
cobegin
process philosopher_i( ){
while(ture){
think( );
P(fork[i]);
P(fork[(i+10%5]);
eat();
V(fork[i]);
V(fork[(i+10%5]);
}
}
coend
3、读写文件问题
int readcount=0;
semaphore writeblock=1,mutex=1;
cobegin
process reader_i() {
P(mutex);
readcount++;
if(readcount==1)
P(writerblock);
V(mutex);
/*读文件*/
P(mutex);
readcount--;
if(readcount==0)
V(writeblock);
V(mutex); }
coend
4、理发师问题
wait=0:顾客信号量
barber=0:理发师信号量
custNum:当前顾客数量
mutex=1:互斥量
Barber(){
while(1){
P(wait); //唤醒等待的一位顾客
P(mutex); //顾客被唤醒,准备理发,没有顾客,则睡觉
custNum--; //当前店里顾客数减1
V(barber); //有顾客来了,醒来理发
V(mettux): //释放互斥信号量
}
}
Customer(){
while(1){
P(mutex); //顾客想要理发
if(custNum<N){ //店里人没有满
custNum++;
V(wait); //理发师睡觉的话,唤醒他理发
V(mutex); //释放互斥量,理发这一动作成功
P(baber); //理发师进行理发操作
}
else
{
V(metux); //释放互斥量,打消进店理发的举动
}
}
}
5、在一间酒吧里有三个音乐爱好者队列,第一队的音乐爱好者只有随身听,第二队只有音乐磁带,第三队只有电池。而要听音乐就必须随身听、音乐磁带和电池这三种物品俱全。酒吧老板一次出售这三种物品中的任意两种。当一名音乐爱好者得到这三种物品并听完一首乐曲后,酒吧老板才能再一次出售这三种物品中的任意两种。于是第二名音乐爱好者得到这三种物品,并开始听乐曲。全部买卖就这样进行下去。试用P,v操作正确解决这一买卖。
semaphore muext=1;
cobegin
process boss(){
P(muext);
/*老板任意出售两种*/
V(muext);
}
process musiclovers_i() {
while(ture){
P(muext);
listening();
V(muext);
}
coend
6、某银行有人民币储蓄业务,由n个储蓄员负责。每个顾客进入银行后先取一个号,并且等着叫号。当一个储蓄人员空闲下来,就叫下一个号。请用P,V操作正确编写储蓄人员和顾客进程的程序。
Var mutex=1,customer_count=0:semaphore;
cobegin
process customer
begin
repeat
P(mutex);
取号码,进入队列;
V(mutex);
V(customer_count);
untile false;
end
process serversi(i=1...n)
begin
repeat
P(customer_count);
P(mutex);
从队列中取下一个号码;
V(mutex);
为该号码持有者服务;
untile false;
end
coend
7、面是两个并发执行的进程。它们能正确运行吗?若不能请举例说明,并改正之。
parbegin
var X:integer;
process P1 process P2
var y,z:integer: var t,u:integer;
begin begin
x:=1; x:=0:
y:=0: t=0;
if x≥l then y:=y十1; if x≤l then t:=t+2;
z:=y; u:=t;
end; end;
parend.
cobegin
Var x:integer; s:semaphore;
s:=A
Process PA Process PB
Var y, z:integer; Var t, u:integer;
Begin Begin
p(s); p(s);
x:=A; x:=0;
y:=0; t:=0;
if x>=A then y:=y+A; if x<A then t:=t+B;
v(s); v(s);
z:=y; u:=t;
End End
coend
8、在一个盒子里,混装了相等数量的黑棋子和白棋子,现要用自动分拣系统把黑棋子和白棋子分开,该系统由两个并发执行的进程P1和P2组成,其中进程P1专门拣黑子,进程P2专门拣白子。规定两个进程轮流拣子且每个进程每次只拣一个子。当一个进程在拣子时不允许另一个进程去拣子,并设P1先拣。请用P,V操作管理这两个并发进程,使其能正确实现上述功能。
var s1,s2:semaphore;
s1:=1;
s2:=0;
cobegin
Process p1
begin
repeat
P(s1);
拣黑子;
V(S2);
untile false;
end
process p2
begin
repeat
P(s2);
拣白子;
V(s1);
untile false;
end
coend