1、利用信号量实现前驱关系
例题1:利用信号量描述如图所示进程间的前趋关系,说明需设置几个信号量,初值是多少?写出进程代码。
答案解析:设有两个并发执行的进程P1和P2。P1中有语句S1,P2中有语句S2。要实现S1执行后再执行S2,为实现这种前驱关系,只需使进程P1和进程P2共享一个公用信号量S,并赋予其初值为0,将Signal(S)操作放在语句S1后面,而在S2语句前面插入一个wait(S)操作即
在进程P1中。用S1;signal(S);
在进程P2中,用wait(S);S2;
为了使得各个程序能够正确执行,应该设置若干个初始值为0的信号量。如为保证S1->S2,S1->S3的前驱关系,应该分别设置信号量a和b,同样再设置信号量c,d,e,f,g
正确答案:
需要设置7个信号量,初值为0
2、生产者——消费者问题
例题1:
银行的储蓄业务流程,n个柜员,一台取号机,顾客进入银行,需要到取号机取号码,如有人正在取,则等待别人取完再取。取完号后等待叫号。当柜员空闲时,会叫下一号。试用PV操作完成顾客和柜员的同步与互斥。
答案解析:
顾客相当于生产者,柜员相当于消费者,所有顾客领取号码后就进入了一个等待队列,该等待队列相当于缓冲区。这个问题基本符合一般意义的“生产者一消费者”问题,但又有所不同,不同在于顾客(即生产者)“取号进入等待队列”操作不需要与柜员(消费者)同步,所以,只需要两个信号量即可,一个用于互斥访问等待队列(对于顾客,就是互斥使用柜员机取号;对于柜员,就是叫号时候互斥访问等待队列),一个用于柜员“叫号”操作与顾客的同步。
正确答案:
semaphore mutex=A, customer_count=0:
main()
{
Cobegin
Customeri()
{
p(mutex);
取号码,进入队列;
v(mutex);
v(customer_count);
}
serversi()
{
while(A)
{
p(customer_count);
p(mutex);
从队列中取下一个号码;
v(mutex);
为该号码持有者服务;
}
end
Coend