问答题
下面是两个并发执行的进程。它们能正确运行吗?若不能请举例说明,并改正之。
Var x:integer;
Process p1 Process p2
Var y,z:integer; Var t,u:integer;
Begin Begin
x:=1; ① x:=0; ②
y:=0; ③ t:=0; ⑥
if x>=1 then y:=y+1; ④ if x<=1 then t:=t+2; ⑦
z:=y; ⑤ u:=t; ⑧
end end
【正确答案】遍历x是两个进程的共享资源,在进程同时申请访问时很容易出错。若采用顺序执行的方法,结构为y=1,z=1,t=2,u=2;若采用并发的方式,并按顺序①②③④⑤⑥⑦⑧执行,则结果为y=0,z=0,出错。改正的方法是为临界资源x设置信号量S,初值为1。程序如下: Parbegin Var x:integer; Process P1 Process P2 Vat y,z:integer; Var t,u:integer; Begin Begin P(S); P(S); x:=1; ① x:=0; ② y:=0; ③ t:=0; ⑥ if x>=1 then y:=y+1; ④ if x<=1 then t:=t+2; ⑦ V(S); V(S); z:=y; ⑤ u:=t; ⑧ end end Parend
【答案解析】
问答题
兄弟俩共同使用一个账号,每次限存或取10元,存钱与取钱的进程分别如下所示:
begin
amount:integer:
amount:=0;
cobegin
Process SAVE
m1:integer:
begin
m1:=amount:
m1:=m1+10;
amount:=m1;
end;
Process TAKE
m2:integer;
begin
m2:=amount;
m2:=m2-10;
amount:=m2;
end;
coend;
end;
由于兄弟俩可能同时存钱和取钱,因此两个进程是并发的。若哥哥先存了两次钱,但在第3次存钱的时候弟弟在取钱,请问最后账号amount上面可能出现的值?如何用P操作、V操作实现两并发进程的互斥执行?
【正确答案】哥哥存两次钱后,amount=20,第三次存钱时,弟弟正在取钱,因没有对amount互斥操作,故发生错误。最后amount上可能出现的值应与两进程相对执行速度有关;若TAKE执行结束后SAVE才开始,则剩20元;若SAVE执行结束后TAKE才开始,也剩20元;问题就出在两个进程交替使用CPU时,则会出现不同值。关键在于最后被执行的语句是amount:=m1,还是amount:=m2,若先amount:=m1后amount:=m2,则amount=10,反之,先amount:=m2后amount:=m1,则amount=30。设信号量mutex(初值为1)控制两进程对变量amount的互斥使用。正确过程如下: begin amount:integer; amount:=0; cobegin Process SAVE m1:integer; Begin P(mutex); m1:=amount; m1:=m1+10; amount:=m1; V(mutex); end; Process TAKE m2:integer; Begin P(mutex); m2:=amount; m2:=m2-10; amount:=m2; V(mutex); end; coend; end;
【正确答案】思路如下: type semaphore=monitor; var acknowledgement1,acknowledgement2,acknowledgement3:boolean; x,y:condition; a,b,c:integer; 指挥官:begin while acknowledgement1==false or acknowledgement2==false or acknowledgement3==false do x.wait; 下达命令; a:=1; b:=1; c:=1; y.signal; end 士兵1:begin while a==0 do y.wait; 接收命令; acknowledgement1=true; x.signal; end 士兵2:begin while a==0 do y.wait; 接收命令; acknowledgement2:true; x.signal: end 士兵3:begin while a==0 do y.wait; 接收命令; acknowledgement3:true; X.signal; end begin a:=0; b:=0; c:=0; acknowledgement1:=false; acknowledgement2:=false; acknowledgement3:=false; end