近日,一直在思考操作系统老师留给我们的一个进程同步问题。
问题是这样的:一个理发店由一个有N张沙发的等待室和一个放有一张理发椅的理发室组成。没有顾客要理发时,理发师便去睡觉。当一个顾客走进理发店时,如果所有的沙发都已被占用,他便离开理发店;否则,如果理发师正在为其他顾客理发,则该顾客就找一张空沙发坐下等待;如果理发师因无顾客正在睡觉,则由新到的顾客唤醒理发师为其理发。在理发完成后,顾客必须付费,直到理发师收费后才能离开理发店。试用信号量实现这一同步问题。并编写一程序进行模拟。
因为刚学过进程管理这一内容。用信号量实现并不困难。
分析可知:顾客进程和理发师进程之间存在着多种同步关系:
(1)只有在理发椅空闲时,顾客才能坐到理发椅上等待理发师理发,否则顾客便必须等待;只有当理发椅上有顾客时,理发师才可以开始理发,否则他也必须等待。这种同步关系类似于单缓冲(对应于理发椅)的生产者——消费者问题中的同步关系,故可通过信号量empty和full来控制。
(2)顾客理完发后必须向理民师付费,并等理发师收费后才能离开,而理发师则需等待顾客付费,并在收费后通知顾客离开,这可分别通过两个信号量payment和receipt来控制。
(3)等候室中N张沙发是顾客进程竞争的资源,故还需要为它们设置一个资源信号量sofa。
(4)为了控制顾客人数,使顾客能在所有的沙发都被占用时离开理发店,还必须设置玫个整型变量count来外处理理发店中的顾客进行计数,该变量将被多个顾客进程互斥地访问并修改,这可通过一个互斥信号量mutex来实现。
所以为解决这一问题,需要设置一个整型变量count用来对理发店中的顾客进行计数,并需设置6个信号量。其中:mutex用来实现顾客进程对count变量的互斥访问,其初值为1;sofa是对应于等待室中N张沙发的资源信号量,其初值为N;empty表示是否空闲的理发椅,其初值为1;full表示理发椅上是否坐有等待理发的顾客,其初值为0;payment用业等待付费,其初值为0;receipt用来等待收费,其初值为0;具体的算法描述如下:
var count:iteger=0;
mutex,sofa,empty,full:semaphore:=1,N,1,0;
cut,payment,receipt:semaphore:=0,0,0;
begin
parbegin
guest:begin
wai(mutex);
if(count>N) then
begin
signle(mutex);
离开理发店;
end
else
begin
count:=coun+1;
if(count>1) then
begin
wait(sofa);
在沙发中就坐;
wait(empty);
从沙发上起来;
signal(sofa);
end
else /* count=1 */
wait(empry);
在理发椅上就坐;
sinal(full);
理发;
付费;
sinal(payment);
wait(receipt);
从理发椅上起来;
signal(empty);
wait(mutex);
count:=count-1;
signal(mutex);
离开理发店;
end
end
barber:begin
repeat
wait(full);
替顾客理发;
wait(payment);
收费;
sinal(receipt);
untile false;
end
parend
end
算法出来了,但现在问题是如何用程序来模拟呢?
因为我们对C#语言比较熟悉,所以首先想到设计一个windows应用程序来模拟。在C#中命各空间System.Threading定义了许多有关线程同步和互斥的类和方法。但具体该怎样使用我还不得要领,思考中……