【正确答案】在本题中,3个并发进程R、M、P共享了一个可循环使用的缓冲区B,进程R负责从输入设备读字符并存入缓冲单元中,进程M负责将读入字符中的空格符改成“,”,进程P负责处理后字符的打印输出。为此,应设置4个信号量mutex、empty、full1、full2。mutex用于实现对缓冲区的互斥访问,其初值为1;empty表示缓冲区中的可用单元数目,其初值为N;full1表示已读入的字符个数,其初值为0;full2表示已处理的字符个数,其初值为0。为了描述方便,还应设置3个指针in、out1、out2。in指向下一个可用缓冲单元,out1指向下一个待处理字符,out2指向下一个待输出字符。它们并发执行的同步机制描述如下:
Semaphore empty=N;
Semaphore full1=0;
Semaphore full2=0;
Semaphore mutex=1;
Char buffer[N];
Int in=0,out1=0,out2=0;
R()
{
While(true)
{
Char x;
读入一个字符到x;
P(empty);
P(mutex);
Buffer[in]=x;
in=(in+1)%N;
V(mutex);
V(full1);
}
}
M()
{
Char x;
While(true)
{
P(full1);
P(mutex);
x=buffer[out1];
If(x==" ")
{
x=",";
Buffer[out1]=x;
}
out1=(out1+1) % N;
V(mutex);
V(full2);
}
}
P()
{
Char x;
While(true)
{
P(full2);
P(mutex);
x=butter[out2];
out2=(out2+1) % N;
V(mutex);
V(empty);
输出字符x;
}
}
本题是生产者-消费者问题的一个衍生问题,较原始问题加入了一个既是生产者也是消费者的进程M。本题中有两个生产者和两个消费者,因此加入了mutex互斥信号量来保证对缓冲区的互斥访问,使题目解答更加严谨。但是由于R、M、P所使用的是不同的指针(分别是in、out1、out2),所以这里不用mutex信号量也能保证进程对缓冲区的互斥访问(注意与2.3.4节经典同步问题中生产者-消费者问题特别注意2的区别)。
如果题目中的若干消费者或若干生产者使用的是相同的指针,就需要设置互斥信号量来保证对缓冲区的互斥访问。
【答案解析】