signal ( SG1 , SG1_count , IM ) ; end :
procedure put2 ( B ) : begin
if inc2 =10 then wait ( SP2 , SP2_count , IM ); Inc2 :=inc2 + 1 ; F2 [in2]:=B;
in2:=(in2 + 1 ) MOD 10
signal ( SG2 , SG2_count , IM ) ; end ;
procedure get ( A , B ) ; begin
if inc1=0 then wait ( SG1 , SG1_count , IM ) ; if inc2=0 then wait ( SG2 , SG2_count , IM ) ; inc1:=inc1-1 ; inc2:=inc2-1; A:F1[out1];
out1:=(out1 + 1 ) MOD 10 B:=F2[out2];
Out2 :=(out2 + 1 ) MOD 10
signal ( SP1 , SP1_count , IM ) ; signal ( SP2 , SP2_count , IM ) ; end ;
begin
in1:=0 ;in2:=0;out1:=0;out2:=0;inc1:=0;inc2:=0 ; SP1:=0;SP2:=0;SG1:=0;SG2:=0; end.
cobegin {
process Produce1 begin while(true) {produce A零件; P(IM.mutex);
Call produceprodut.put1(A); If IM.next>0 then V(IM.next); Else V(IM,mutex); } End;
Process Produce2 Begin While(true) {produce B零件; P(IM.mutex);
Call produceprodut.put2(B); If (IM.next>0 then V(IM.next); Else V(IM,mutex); }
Process consume Begin While(true) {
P(IM.mutex);
Call produceprodut.get(A,B); If IM.next>0 then V(IM.next); Else V(IM,mutex); 组装产品; }
End; } Coend.
38 桌上有一只盘子,最多可以容纳两个水果,每次仅能放入或取出一个水果。爸爸向盘子中放苹果(apple ) ,妈妈向盘子中放桔子(orange ) ,两个儿子专等吃盘子中的桔子,两个女儿专等吃盘子中的苹果.试用:( 1 )信号量和P 、v 操作,( 2 )管程,来实现爸爸、妈妈、儿子、女儿间的同步与互斥关系. 答:( l )用信号量和P 、v 操作.
类似于课文中的答案,扩充如下:1 )同步信号量初值为2 ; 2 )要引进一个互斥信号量mutex , 用于对盘子进行互斥:3 )盘子中每一项用橘子、苹果2 个枚举值。
Var
plate ARRAY [ 0 , 1] of ( apple , orange ) ; flag0 , fiag1:=boolean ; mutex : semaphore ;
sp : semaphore; / *盘子里可以放几个水果*/
sg1 , sg2 : semaphore ; / *盘子里有桔子,有苹果* /
sp : = 2 ; / *盘子里允许放入二个水果*/
sg1 :=sg2 :=0 ; / *盘子里没有桔子,没有苹果*/
flag0:=flag1:=false ; mutex :=1 :
cobegin process son process father begin
begin L3 : P (sg1 ) ; L1 :削一个苹果; P( mutex ) ;
P ( sp ) ; if(flag0&flte[0]==桔子) then
If(flag0==false) then else{x:=plate[1];flag1:=false;}
{ plate[0]:=苹果;flag1:=true;} v(mutex); else {plate[1]:=苹果;flag1:=true;} V(sp) ; v (mutex ); 吃桔子;
v(sg2) goto L3; goto Ll ; end; end ;
process mother process daughter begin begin
L2 :剥一个桔子; L4 : P ( 592 ) : P ( sp ) ; P ( mutex )
P ( mutex ) ; if ( flag0 & plate [0]==苹果)then
if ( flag0==false )then {x:=plate [01]; flag0:=false ; }
{plate[0]:=桔子;flag0:=true;) else { x:==plate[1] ; flag1:=false ; }
else {plate[1]:==桔子;flag1:=true ; } V ( mutex ) ; V (mutex) ; V ( sp ) ; V (sg1) ; goto L2 ; goto L4; end ; end ; coend . ( 2 )用管程.
TYPE FMSD = MONITOR
VAR plate ARRAY [ 0 , 1 ] of ( apple , orange ) ;
Count:integer ; flag0,flag1:boolean ; SP ,SS , SD : codition ; DEFFINE put,get ;
USE wait,signal , check , release ;
procedure put(var fruit:( apple ,orange ) ) ; begin
check(IM ) ;
if ( count==2 ) then wait(SP , IM ) ; else{if(flag0==false) then {plate[0]:=fruit; flag0:=true;} Else{plate[1]:=fruit;flag1:=true;}
吃苹果; Count:=count+1;
If(fruit==orange) then signal(ss,IM); Else signal(SD,IM); }
Release(IM); End;
Procedure get(varfruit:(apple,orange),x:plate); Begin Check(IM);
If (count==0) or plate <>fruit Then begin
If(fruit==orange) then wait(SS,IM); Else wait(SD,IM); End;
Count:=count-1;
If(flag0&plate[0]==fruit) then {x:=plate[0];flag0:=false;} Else{x:=plate[1];flag1:=false;} Signal(SP,IM); Release(IM); End; Begin
Count:=0;flag0:=false;flag1:=false; SP:=0;ss:=0;sd:=0; Plate[0]:plate[1]:=null;