用信号量进程同步与互斥

1.理解生产者和消费者问题

没有引入信号量时的生产者和消费者进程,什么情况下会出现结果不唯一?什么情况下会出现永远等待?

答:当生产者生产完商品之后,在商品进入等待队列之前发生中断,会出现结果不唯一的情况;

当最后一个商品进入等待队列之后,在唤醒消费者之前发生中断,会出现等待队列已满,生产者在等待消费者消费,消费者则等待生产者唤醒,即出现永远等待的情况。

 

用信号解决生产者和消费者的同步与互斥,要求能自己写出来。

int empty = 1;
int full = 0;
int mutex = 1;
process product(){
  whiile(true){
    process();  
    P(empty);
    P(mutex);
    商品数加一
    V(mutex);
    V(full);
    }
}
 process consume(){
  while(true){
       P(full);
      P(mutex);
      商品减一
      V(mutex);
      V(empty);
      consume();
    }
}           

 

2.哲学家吃面问题

semaphore fork[5];
for(int i;i<=5;i++){
    fork[i];
}
process philosopher(){
    while(true){
        think();
        P(fork[i]);
        P(fork[(i+1)%5];
        eat();
        V(fork[i]);
        V(fork[(i+1)%5);
    }
}

3.读写文件问题

int readcount = 0;  //读进程计数
semaphore writeblock = 1;  //写信号量
semaphore mutex  = 1;  //互斥信号量
process read(){
    P(mutex);
    readcount++;
    if(readcount==1){
        P(writeblock);
        V(mutex);
        读文件;
        P(mutex)
        readcount--;
        if(readcount==0){
            V(writeblock);
        }
        V(mutex);
    }
}    

process write(){
    P(writeblock);
    写文件;         
    V(writeblock);
}

4.理发师问题

int writing = 0;
int chair = n;
semaphore customer = barbers = 0;
semaphore mutex=1;
process barber(){
    while(true){
        P(customers);    //判断是否有顾客,若无顾客。理发师睡眠
        P(mutex);    //若有顾客,进入临界区
        writing--;    //等待人数减一
        V(barber);   //理发师准备为顾客理发
        V(mutex);    //退出临界区
        cuthair();    //理发师正在理发(非临界区)
    }
}
process customer(){
    P(mutex);    //进入临界区
    If(waiting < chair){    //判断是否有空椅子
        writing++;    //若有空椅子,等待人数加一
        V(customer);    //唤醒理发师
        V(mutex);    //退出临界区
        P(barber);    //理发师忙,顾客坐着等待
        get_haircut();    //否则,顾客可以理发
    }else
        V(mutex);    //人满了,顾客离开
}        

5.在一间酒吧里有三个音乐爱好者队列,第一队的音乐爱好者只有随身听,第二队只有音乐磁带,第三队只有电池。而要听音乐就必须随身听、音乐磁带和电池这三种物品俱全。酒吧老板一次出售这三种物品中的任意两种。当一名音乐爱好者得到这三种物品并听完一首乐曲后,酒吧老板才能再一次出售这三种物品中的任意两种。于是第二名音乐爱好者得到这三种物品,并开始听乐曲。全部买卖就这样进行下去。试用P,V操作正确解决这一买卖。

semaphore S1=S2=S3=music_over = 0;
parbegin{
    fan1:begin{
        wait(S1);
        买音乐磁带和电池;
        听乐曲;
        signal(music_over);
    }end
    fan2:begin{
        wait(S2);
        买随身听和电池;
        听乐曲;
        signal(music_over);
    }end
    fan3:begin{
        wait(S2);
        买随身听和音乐磁带;
        听乐曲;
        signal(music_over);
    }end
    boss:begin{
        repeat
            提供任意两种物品出售;
            if(提供的是音乐磁带和电池)
                signal(S1);
            else if(提供的是随身听和电池)
                signal(S1);
            else
                signal(S1);
        until false;
        }end
}parend

 

6.某银行有人民币储蓄业务,由n个储蓄员负责。每个顾客进入银行后先取一个号,并且等着叫号。当一个储蓄人员空闲下来,就叫下一个号。请用P,V操作正确编写储蓄人员和顾客进程的程序。

Semaphore mutex = 1,full = 无穷;
Cobegin{
  customer(){
    While(1){
      Wait(mutex);
      取号;
      Signal(mutex);
      等待;
      Signal(full);
   }
  }
  bank(){
    While(1){
      Wait(full);
      Wait(mutex);
      叫号;
      Signal(mutex);
      服务;
    }
  }
}Coend;

7.下面是两个并发执行的进程。它们能正确运行吗?若不能请举例说明,并改正之。(5分)

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.

 答:进程不能正确执行。当进程执行答进程1中的"x:=1"出现中断请求执行进程2,执行进程2时把x的值改为了0,进程2执行完毕后返回继续执行进程1时,x的值已经由原来的1变为了0,将导致进程执行的结果出现错误。导致进程结果不正确的是因为进程1和2没有实现互斥,在x的值改变之前就要给利用互斥信号量给相应的进程上锁,直到进程执行到与x的值变化无关时才能为进程解锁。具体修改如下:

parbegin

    var X:integer;

 semaphore mutex;

 mutex = 1;

    process  P1                    process  P2

    var y,z:integer:            var t,u:integer;

     begin                          begin

       P(mutex);      P(mutex);

  x:=1;                           x:=0:

       y:=0:                           t=0;   

       if  x≥l  then y:=y十1;    if  x≤l  then  t:=t+2;

           V(mutex);      V(mutex);

   z:=y;                           u:=t;

     end;                         end;

parend.

 

8.在一个盒子里,混装了相等数量的黑棋子和白棋子,现要用自动分拣系统把黑棋子和白棋子分开,该系统由两个并发执行的进程P1和P2组成,其中进程P1专门拣黑子,进程P2专门拣白子。规定两个进程轮流拣子且每个进程每次只拣一个子。当一个进程在拣子时不允许另一个进程去拣子,并设P1先拣。请用P,V操作管理这两个并发进程,使其能正确实现上述功能。

semaphore S1,S2;    //信号量S1、S2分别表示白子、黑子
S1 = 1,S2 = 0;    
cobegin{
    process P1
    begin{
        repeat
        P(S1);
        拣白子
        V(S2);
        until false;
    }end
    process P2
    begin{
        repeat
        P(S2);
        拣黑子
        V(S1);
        until false;
    }end
}coend

 

posted @ 2019-05-05 18:45  MrHsj  阅读(311)  评论(0编辑  收藏  举报