问答题 今有3个并发进程R、M、P,它们共享一个可循环使用的缓冲区B,缓冲区B共有N个单元。进程R负责从输入设备读信息,每读一个字符后,把它存入缓冲区B的一个单元中;进程M负责处理读入的字符,若发现读入的字符中有空格符,则把它改成“,”;进程P负责把处理后的字符取出并打印输出。请用P、V操作作为同步机制写出它们能正确并发执行的程序。
【正确答案】在本题中,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的区别)。 如果题目中的若干消费者或若干生产者使用的是相同的指针,就需要设置互斥信号量来保证对缓冲区的互斥访问。
【答案解析】