var Fl , F2 : ARRAY [ 0?9 ] of item; SP1 , SP2 , SI1 , SI2:seMaphore ; in1 , in2 ,outl ,outZ :integer ; in1:=0;in2:=0;out1:=0;out2:=0; SP1:=10;SP2:=10;SI1:=0;SI2:=0; Main() {cobegin
Producer1(); Producer2(); Installer() Coend }
Process producer1() Begin
While(true) {
Produce A零件; P(SP1); F1[in1]:A;
In1:=(in1+1) mod 10 V(SI1); } End
Process producer2() Begin
While(true) {
Produce B零件; P(SP2); F2(in2):=B;
In2:=(in2+1) mod 10 V(SI2); } End
Process installer() Var product:item; Begin
While(true) { p(SI1);
Product1:=F1[out1]; Out1:=(out1+1) mod 10; V(SP1); P(SI2);
Product2:=F2[out2];
Out2:=(out2+1) mod 10; V(SP2); 组装产品; } End
TYPE produceprodut=monitor
VAR F1 , F2 : ARRAY [ 0 ?9 ] of item; SP1 , SP2 , SG1 , SG2:semaphore;
SP1_count1,SP2 count2 , SG1_count,SG2_count:integer; In1, in2 ,out1 ,out2:=integer ; inc1 , inc2 : integer ; DEFINE put1 , put2 , get : USE wait,signal; procedure put1( A ); begin
if inc1=10 then wait ( SP1 , SP1_count , IM ); Inc1:=inc1 + 1 : F1[in1]:= A ;
in1:=(in1 + 1 ) MOD 10
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; End; Main() {cobegin
Process father Begin While(1)
{准备好苹果;
Call FMSD.put(apple); ?? } End;
Process mother Begin While(1) {