{ waiting= waiting+1; // 等候顾客数加1 V(customers); //必要的话唤醒理发师 V(mutex); //开放临界区
P(barbers); //无理发师, 顾客坐着养神 get-haircut( ); //一个顾客坐下理发/ } else
V(mutex); //人满了,走吧!
}
5.19 进程之间有哪些基本的通信方式?它们分别有什么特点?适用于哪些场合?
答:进程通信根据交换信息量的多少分为高级通信和低级通信。低级通信一般只传送一个或几个字节的信息,以达到控制进程执行速度的作用(如PV操作);高级通信则要传送大量数据,目的不是为了控制进程的执行速度,而是为了交换信息。
高级进程通信方式有很多种,大致可归并为三类:共享存储器、管道文件和消息传递。
共享存储器:在内存种分配一片空间作为共享存储区。需要进行通信的进程把它附加到自己的地址空间中,不需要时则把它取消。
管道文件:它是连接两个命令的一个打开文件。一个命令向该文件中写入数据,为写者;另一个命令从该文件中读出数据,为读者。
消息传递:它以消息为单位在进程间进行数据交换。 5.20 试比较进程间的低级通信工具与高级通信工具。
答:用户用低级通信工具实现进程通信很不方便,因为其效率低,通信对用户不透明,所有的操作都必须由程序员来实现。而高级通信工具则可弥补这些缺陷,用户可直接利用操作系统所提供的一组通信命令,高效地传送大量的数据。 5.21 试用信箱通信方式解决生产者-消费者问题。
答:在本题解决方案中,使用了两个信箱mayproduce和mayconsume,两个信箱的大小均为N,即其中最多可以存放N条消息。当生产者生产了数据时,它将数据作为消息发送到信箱mayconsume,只要该信箱中有一条消息,消费者就可以开始消费。信箱mayproduce最初填满了空消息,空消息的条数等于信箱的容量与mayconsume信箱中消息条数之差(其作用类似于用信号量机制解决生产者一消费者问题中的empty)。当生产者向消费者发送一条消息时,mayproduce信箱中的消息条数减少,mayconsume信箱中的消息条数增加;当消费者接收一条消息时,mayconsume信箱中的消息条数减少,而mayproduce信箱中的消息条数增加。系统中的消息总条数保持不变。 const int capacity=N; /*N为信箱容量*/ null=...; /*这里“...”为空消息*/ int i;
main( ) /*主程序*/ {
create_mailbox(mayproduce); /*创建信箱 mayproduce*/ create_mailbox(mayconsume); for(i=1; i<=capacity; i++) send(mayproduce, null); cobegin
producer( );
consumer(); coend }
producer( ) /*生产者进程*/ {
message pmsg; /* message 为消息类型*/ while (true) {
receive(mayproduce, pmsg); /*等待空消息*/ pmsg=produce(); /*生产一条消息*/
send(mayconsume, pmsg); }
}
consumer( ) /*消费者进程*/ {
message cmsg; while (true) {
receive(mayconsume, cmsg);
consume(cmsg); /*取出一条消息供消费*/
send(mayproduce, null);
} }
5.22 在消息传递通信方式下:
(1)发送进程和接收进程在通信过程中可以采用哪3种同步方式?
(2)试以下面给出的发送进程和接收进程(将接收到的数据存入S)为例,说明当接收进程执行到标号为L2的语句时,采用这3种同步方式,X的值可能各是多少?
发送进程P:
M=10;
L1:sendMTOQ; L2:M=20; GotoLl; 接收进程Q:
S=-100;
L1:receiveSfromP; L2:X=S+1; 答:
(1)发送进程阻塞,接收进程阻塞。
发送进程不阻塞,接收进程阻塞。 发送进程不阻塞,接收进程也不阻塞。
(2)在第1种同步方式下,无论进程P还是Q都必须等到对方执行完标号为L1的语句后才可往下执行,S的值一定为M的初值10,所以X只能为11。
在第2种同步方式下,如果进程P先执行到标号为L1的语句,由于无需阻塞,仍可往下执行,而进程Q在执行到标号为L1的语句时,可能进程P尚未来得及向Q发出第2条消息,也可能进程P已经向Q发出了多条消息。在前一种情况下,S的值为10;
在后一种情况下,S的值为20,故X的值可能为11或21。
在第3种同步方式下,如果进程P先执行到标号为L1的语句,由于无需阻塞,仍可往下执行,而进程Q在执行到标号为L1的语句时,可能进程P尚未来得及向Q发出第1条消息,也可能进程P已经向Q发出了一条或多条消息。在前一种情况下,S的值为—100;在中间一种情况下,S的值为10;在后一种情况下,S的值为20。故X的值可能为-99、11或21。