理发师问题

来源:互联网 发布:怎么查看淘宝信誉积分 编辑:程序博客网 时间:2024/05/01 04:25
     理发师问题:
     一个理发店由一个有几张椅子的等待室和一个放有一张理发椅的理发室组成。
     1. 若没有要理发的顾客,则理发师去睡觉;
     2. 若一顾客进入理发店,理发师正在为别人理发,且等待室有空椅子,则该顾客就找张椅子按顺序坐下;
     3. 若一顾客进入理发店,理发师在睡觉,则叫醒理发师为该顾客理发;
     4. 若一顾客进入理发店且所有椅子都被占用了,则该顾客就离开。
    伪码实现:

    引入3个信号量和一个控制变量:

    1)控制变量waiting用来记录等候理发的顾客数,初值均为0; 

    2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0; 

    3)信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为0(刚开始时理发师在睡觉,所以理发师这个资源数目为0); 

    4)信号量mutex用于互斥,初值为1. 

    关于p,v操作:

     P操作可以看做是申请一个资源,不管这个资源有没有都将这个资源的数目减1,如果现在资源数目小于0,就阻塞。

     v操作就是释放资源,先将这个资源的数目加1,如果发现这个资源数目小于等于0,就会唤醒在阻塞队列上的一个进程。

     先做一些初始化工作:

var waiting : integer; /*等候理发的顾客数*/CHAIRS:integer; /*为顾客准备的椅子数*/ customers, barbers,mutex : semaphore; customers := 0; barbers := 0; waiting := 0; mutex := 1;

     理发师进程:

Procedure barber; begin while(TRUE); /*理完一人,还有顾客吗?*/ P(cutomers); /*若无顾客,理发师睡眠*/ P(mutex); /*进程互斥*/ waiting := waiting – 1; /*等候顾客数少一个*/ V(barbers); /*理发师去为一个顾客理发,如果babaers等于0,则顾客都会阻塞*/ /*刚开始时babers = 0,表示理发师这个资源为0,所以顾客进程执行至P(barbers)时也无法让理发师为其理发,现在理发师醒了,表示理发店里拥有理发师这个资源了,所以执行V(barbers)这个操作,将资源数加1,此时会唤醒一个在队列上阻塞的顾客*/V(mutex); /*开放临界区*/ cut-hair( ); /*正在理发*/ end; 


    顾客进程:

procedure customer begin P(mutex); /*进程互斥*/ if (waiting < n) waiting := waiting+1; /* n表示椅子的数目,等候顾客数加1*/ V(customers); /*必要的话唤醒理发师*/ V(mutex); /*开放临界区*/ P(barbers); /*无理发师, 顾客坐着养神*/ get-haircut( ); /*一个顾客坐下等理发*/ end V(mutex); /*人满了,走吧!*/ end; 



原创粉丝点击