2.3 进程的同步

74
1 2.3 进进进进进 • 进进进进进进 进进进进进进进进进进进进 进进进进进进进 ,, 进进进进进进进进进进进进进进 进进进进进进进进进进进进进进 进进进进进进进进• 进进进进进进进进进进进进进进进进进进进进进进进进进进进进进进 • 进进进进进进进──进进进进 P.V 进进 进进进进进进进进进

description

2.3 进程的同步. 在多道程序系统中,由于资源共享或进程合作,使进程间形成间接相互制约和直接相互制约关系,这需要用进程互斥与同步机制来协调两种制约关系。 进程同步的主要任务是使并发执行的进程间有效的共享资源和相互合作, 进程的同步机制──信号量及 P.V 操作(解决进程同步互斥问题). 2.3.1 进程同步的基本概念. 1. 两种形式的制约关系 直接相互制约关系 ( 同步 ) 间接相互制约关系 ( 互斥 ) 共享变量 直接作用 ( 相互合作): 进程间的相互联系是有意识的安排的,直接作用只发生在相交进程间 间接作用 (资源共享): - PowerPoint PPT Presentation

Transcript of 2.3 进程的同步

Page 1: 2.3  进程的同步

1

2.3 进程的同步

• 在多道程序系统中,由于资源共享或进程合作,使进程间形成间接相互制约和直接相互制约关系,这需要用进程互斥与同步机制来协调两种制约关系。

• 进程同步的主要任务是使并发执行的进程间有效的共享资源和相互合作,

• 进程的同步机制──信号量及 P.V 操作(解决进程同步互斥问题)

Page 2: 2.3  进程的同步

2

• 1. 两种形式的制约关系• 直接相互制约关系 ( 同步 )• 间接相互制约关系 ( 互斥 )• 共享变量

直接作用 ( 相互合作):进程间的相互联系是有意识的安排的,直接作用只发生在相交进程间

间接作用(资源共享):进程间要通过某种中介发生联系,是无意识安排的,可发生在相交进程之间,也可发生在无关进程之间

2.3.1 进程同步的基本概念

Page 3: 2.3  进程的同步

3

“ 临界资源” (Critical Resource) :一段时间内只允许一个进程访问的资源

Page 4: 2.3  进程的同步

4

交往的并发进程(结果不唯一)机票问题

process Ti ( i = 1, 2 )

var Xi:integer;

begin

{ 按旅客定票要求找到 Aj} ;Xi := Aj;

if Xi>=1 then begin

Xi:=Xi-1; Aj:=Xi;{ 输出一张票 } ; end

else { 输出票已售完 } ;end;

Page 5: 2.3  进程的同步

5

进程的交往:第一种是竞争关系

•系统中的多个进程之间彼此无关

•系统中的多个进程之间彼此相关

Page 6: 2.3  进程的同步

6

进程互斥 (Mutual Exclusion)•解决进程间竞争关系 ( 间接制约关系 )的手段。

•进程互斥指若干进程要使用同一共享资源时,任何时刻最多允许一个进程使用,其他进程必须等待,直到占有资源的进程释放该资源。

Page 7: 2.3  进程的同步

7

第二种是协作关系 (1)•某些进程为完成同一任务需要分工协作。

• 进程的同步是解决进程间协作关系 (直接制约关系 )的手段。

Page 8: 2.3  进程的同步

8

• 进程同步指两个以上进程基于某个条件来协调它们的活动。一个进程的执行依赖于协作进程的消息或信号,当一个进程没有得到来自于协作进程的消息或信号时需等待,直到消息或信号到达才被唤醒。

Page 9: 2.3  进程的同步

9

•进程互斥关系是一种特殊的进程同步关系,即逐次使用互斥共享资源,是对进程使用资源次序上的一种协调。

Page 10: 2.3  进程的同步

10

生产者 --消费者问题表述 有界缓冲问题

•有 K 个生产者和 m 个消费者,连接在一个有 n 个单位缓冲区的有界缓冲上。其中, producer 和 consumer 都是并发进程,只要缓冲区未满,生产者 p 生产的产品就可投入缓冲区;只要缓冲区不空,消费者进程c就可从缓冲区取走并消耗产品。

Page 11: 2.3  进程的同步

11

生产者 -消费者问题算法描述(1)• var n,integer;

• type item=…;

• var buffer:array[0...n-1] of item;

• in,out:0,1,…n-1;

• counter:integer:0,1,…n;

Page 12: 2.3  进程的同步

12

生产者 -消费者问题算法描述(2)•Producer:repeat

• .•  produce an item in nextp ;• .   while counter=n do no-op;   buffer[in]:=nextp;    in:=(in+1) mod n;    counter:=counter+1    until false ;

Page 13: 2.3  进程的同步

13

生产者 -消费者问题算法描述(3)•Consumer:repeat

•   While counter=0 do no-op;• nextc:=buffer[out];• out:=(out+1) mod n;• counter:=counter-1;• consume th e item in nextc;    Until false•

Page 14: 2.3  进程的同步

14

3. 临界区• 并发进程中访问临界资源的那段代码叫

“临界区” (Critical Section)

Page 15: 2.3  进程的同步

15

交往的并发进程(结果不唯一)机票问题

process Ti ( i = 1, 2 )

var Xi:integer;

begin

{ 按旅客定票要求找到 Aj} ;Xi := Aj;

if Xi>=1 then begin

Xi:=Xi-1; Aj:=Xi;{ 输出一张票 } ; end

else { 输出票已售完 } ;end;

Page 16: 2.3  进程的同步

16

基本概念 :• 进程互斥:指在多道程序环境下,每次只允

许一个进程对临界资源进行访问。• 进程同步:指多个相关进程在执行次序上的

协调。• 临界资源 : 一次仅供一个进程使用的资源。• 在进程中涉及到临界资源的程序段叫临界区• 多个进程的临界区称为相关临界区

Page 17: 2.3  进程的同步

17

3.临界区临界区的调度原则:

一次至多允许一个进程进入临界区内一个进程不能无限地停留在临界区内一个进程不能无限地等待进入临界区

Page 18: 2.3  进程的同步

18

4. 使用互斥区的原则• 空闲让进:当无进程在互斥区时,任何

有权使用互斥区的进程可进入• 忙则等待:不允许两个以上的进程同时

进入互斥区• 有限等待:任何进入互斥区的要求应在

有限的时间内得到满足• 让权等待:处于等待状态的进程应放弃

占用 CPU ,以使其他进程有机会得到CPU 的使用权

Page 19: 2.3  进程的同步

19

2 .3.2 信号量机制• 著名的生产者 -- 消费者问题是计算机

操作系统中并发进程内在关系的一种抽象,是典型的进程同步问题。

• 在操作系统中,生产者进程可以是计算进程、发送进程;而消费者进程可以是打印进程、接收进程等等。

• 解决好生产者 -- 消费者问题就解决好了一类并发进程的同步问题。

Page 20: 2.3  进程的同步

20

3) 信号量机制• 信号量机制是一种卓有成效的进程同步工

具,被广泛应用于单处理机和多处理机系统,以及计算机网络中。

• 锁机制仅能表示“开”与“关”两种状态;开、关锁原语必须作为原子操作来进行;关锁原语言中反复测试W状态,浪费了处理机的时间;锁机制只能解决互斥,不能用于同步。信号量同步机制能完满地解决上述问题。

Page 21: 2.3  进程的同步

21

信号量: semaphore• 是一个数据结构• 定义如下: struc semaphore {

int value;pointer_PCB queue;

}

• 信号量说明: semaphore s;

Page 22: 2.3  进程的同步

22

信号量与 PV 操作 (1)• 1965 年 E.W.Dijkstra提出了同步工具 --

信号量和 P 、 V 操作。

Page 23: 2.3  进程的同步

23

•信号量:一种软件资源•原语:内核中执行时不可被中断的过程

•P 操作原语和 V 操作原语

Page 24: 2.3  进程的同步

24

•信号量和 P 、 V 操作 ,将交通管制中多种颜色的信号灯管理交通的方法引入操作系统,让两个或多个进程通过特殊变量展开交互。

Page 25: 2.3  进程的同步

25

•通过信号量传送信号,进程使用 P 、 V 两个特殊操作来发送和接收信号,如果进程相应的信号仍然没有送到,进程被挂起直到信号到达为止。

Page 26: 2.3  进程的同步

26

•操作系统中,信号量表示物理资源的实体,它是一个与队列有关的整型变量。

•实现时,信号量是一种记录型数据结构,有两个分量:一个是信号量的值,另一个是信号量队列的队列指针。

Page 27: 2.3  进程的同步

27

1.整型信号量 设 s 为一个整形量,除初始化外,仅

能通过 P 、 V 操作访问, P 和 V 操作原语定义:

P(s) : while s≤0 do no-op s : =s-1 ; V(s) : s : =s+1 ;

Page 28: 2.3  进程的同步

28

2.记录型信号量 设 s 为一个记录型数据结构 ,一个分量为整形量 value, 另一个为信号量队列 L, P 和 V 操作原语定义:

• P(s) ;将信号量 s减去 l ,若结果小于 0,则调用 P(s) 的进程被置成等待信号量 s 的状态。

• V(s) :将信号量 s加 1 ,若结果不大于 0,则释放一个等待信号量 s的进程。

Page 29: 2.3  进程的同步

29

type semaphore = record value:integer; L: list of process;Endprocedure P(S)var s:semaphore;begin s .value:= s.value – 1; /* 把信号量减去 1 */ if s.value < 0 then block(s,L);/* 若信号量小于 0 ,

则调用 P(s) 的进程被置成等待信号量 s的状态 */end;procedure V(S)var s:semaphore);begin

s .value:= s.value + 1; /* 把信号量加 1 */if s .value<= 0 then wakeup(s,L); /* 若信号量小于等于 0,则释放一个等待信号量 s的进程 */

end;

Page 30: 2.3  进程的同步

30

•推论 1 :若信号量 s 为正值,则该值等于在封锁进程之前对信号量 s 可施行的 P 操作数、亦等于 s 所代表的实际还可以使用的物理资源数

Page 31: 2.3  进程的同步

31

•推论 2 :若信号量 s 为负值,则其绝对值等于登记排列在该信号量 s队列之中等待的进程个数、亦即恰好等于对信号量s实施 P 操作而被封锁起来并进入信号量 s队列的进程数

Page 32: 2.3  进程的同步

32

•推论 3 :通常, P 操作意味着请求一个资源, V 操作意味着释放一个资源。在一定条件下, P操作代表挂起进程操作,而 V 操作代表唤醒被挂起进程的操作

Page 33: 2.3  进程的同步

33

3.AND 型信号量

4. 信号量集

Page 34: 2.3  进程的同步

34

8. 信号量集——AND型信号量集

• AND 型信号量集是指同时需要多种资源且每种占用一个时的信号量操作

• AND 型信号量集的基本思想:在一个原

语中申请整段代码需要的多个临界资源,要么全部分配给它,要么一个都不分配

• AND 型信号量集 P 原语为 Swait• AND 型信号量集 V 原语为 Ssignal

Page 35: 2.3  进程的同步

35

Swait(S1, S2, …, Sn) //P 原语;{

while (TRUE) {if (S1 >=1 && S2 >= 1 && … && Sn >= 1){ // 满足资源要求时的处理; for (i = 1; i <= n; ++i) -–Si;

// 注:与 P 的处理不同,这里是在确信可满足

// 资源要求时,才进行减 1 操作;break;

}else { // 某些资源不够时的处理;

调用进程进入第一个小于 1 信号量的等待队列 Sj.queue;

阻塞调用进程 ; }

Page 36: 2.3  进程的同步

36

Ssignal(S1, S2, …, Sn){

for (i = 1; i <= n; ++i) {

++Si; //释放占用的资源; for ( 在 Si.queue 中等待的每一

个进程 P) //检查每种资源的等待队列的所

有进程; {

从等待队列 Si.queue 中取出进程 P;

Page 37: 2.3  进程的同步

37

if (判断进程 P 是否通过 Swait 中的测试 ) //注:与 signal 不同,这里要进

行重新判断; {// 通过检查(资源够用)时的处理; 进程 P 进入就绪队列 ; } else {//未通过检查(资源不够用)时的处

理; 进程 P 进入某等待队列; } } }

}

Page 38: 2.3  进程的同步

38

9. 一般“信号量集”

• 一般信号量集是指同时需要多种资源、每种占用的数目不同、且可分配的资源还存在一个临界值时的信号量处理

• 一般信号量集的基本思路就是在 AND 型信号量集的基础上进行扩充,在一次原语操作中完成所有的资源申请。

Page 39: 2.3  进程的同步

39

• 进程对信号量 Si 的测试值为 ti (表示信号量的判断条件,要求

Si >= ti ;即当资源数量低于 ti 时,便不予分配)

占用值为 di (表示资源的申请量,即 Si = Si

- di )

对应的 P 、 V 原语格式为:– Swait(S1, t1, d1; ...; Sn, tn, dn);

– Ssignal(S1, d1; ...; Sn, dn);

Page 40: 2.3  进程的同步

40

一般“信号量集”可以用于各种情况的资源分配和释放,几种特殊情况:

• Swait(S, d, d) 表示每次申请 d 个资源,当少于 d 个时,便不分配

• Swait(S, 1, 1) 表示互斥信号量• Swait(S, 1, 0) 可作为一个可控开关(当 S

1 时,允许多个进程进入临界区;当 S=0 时,禁止任何进程进入临界区)

Page 41: 2.3  进程的同步

41

【思考题】

1. 用 P.V 操作解决下图之同步问题 :

get copy put

f s t g

Page 42: 2.3  进程的同步

42

用 P.V 操作解决司机与售票员的问题

司机进程:while (true){

启动车辆

正常驾驶

到站停车}…

售票员进程:while (true){

关门

售票

开门}…

Page 43: 2.3  进程的同步

43

2.3.3 信号量的应用• 1. 利用信号量实现进程互斥•2. 利用信号量实现前趋关系

Page 44: 2.3  进程的同步

44

2) 解决互斥的锁机制

•实现互斥的一种软件方法是采用锁机制,即提供一对上锁 (Lock) 和开锁 (UnLock) 原语,以及一个锁变量W。

• 进程进入临界区前,通过锁变量来判断临界资源是否被占用。

Page 45: 2.3  进程的同步

45

P 操作P(s){ s.value = s.value --; if (s.value < 0) {

该进程状态置为等待状态 将该进程的 PCB插入相应的等待队列末尾

s.queue; }}

Page 46: 2.3  进程的同步

46

P操作• 意味着请求分配一个单位资源

Page 47: 2.3  进程的同步

47

V 操作V(s){ s.value = s.value ++; if (s.value < = 0) { 唤醒相应等待队列 s.queue 中等待的一个

进程 改变其状态为就绪态 并将其插入就绪队列 }}

Page 48: 2.3  进程的同步

48

V操作• 意味着释放一个单位资源

Page 49: 2.3  进程的同步

49

P 、 V 操作为原语操作

原语:是由若干多机器指令构成的完成某种特定功能的一段程序,具有不可分割性。即原语的执行必须是连续的,在执行过程中不允许被中断

实现:开关中断

Page 50: 2.3  进程的同步

50

信号量的使用: 必须置一次且只能置一次初值 初值不能为负数 只能执行 P 、 V 操作

Page 51: 2.3  进程的同步

51

用 P 、 V 操作解决进程间互斥问题

P(mutex)

V(mutex)

P1 P2 P3

互斥区

P(mutex)

P(mutex)

V(mutex)

V(mutex)

Page 52: 2.3  进程的同步

52

互斥例子•三个进程共用两个 I/O 缓冲区。• 解:设用信号量 S 表示共享资源,

S初始值为 2

Page 53: 2.3  进程的同步

53

同步例子• 有 A、 B 两进程, A进程从卡片机读信息入缓冲区, B 进程负责加工读进缓冲区的卡片

• 解:设信号量 S1 :缓冲区中有否可供加工的信息,初始值为 0;信号量 S2 :缓冲区是否为空,初始值为 1 。

Page 54: 2.3  进程的同步

54

同步例子(续)

在输入进程 A中,可以把 P(S2) 调到 V(S1)后面,而把信号量 S2 的初始值设为0。

Page 55: 2.3  进程的同步

55

用 P-V 操作描述前趋关系的例子• 信号量还可以描述程序或语句之间

的前趋关系。

Page 56: 2.3  进程的同步

56

用 P-V 操作描述前趋关系(续)描述如下:Var a , b, c , d, e , f, g: semaphore : =0, 0,0, 0, 0, 0, 0;

begin parbegin begin  S1 ; V(a) ; V(b) ; end; begin  P(a) ; S2 ; V(c) ; V(d) ; end; begin  P(b) ; S3 ; V(e) ; end; begin  P(c) ; S4 ; V(f) ; end; begin  P(d) ; S5; V(g) ; end; begin  P(e) ; P(f) ; P(g) ; S6; end; parend end

Page 57: 2.3  进程的同步

57

记录型信号量解决进程互斥问题 s : semaphore; s := 1;cobegin …… process Pi begin

…… P(s); 临界区; V(s); ……

end; ……

coend;

Page 58: 2.3  进程的同步

58

记录型信号量和 PV 操作解决机票问题(1) • Var A : ARRAY[1..m] OF integer;

• mutex : semaphore;• mutex:= 1;• cobegin• process Pi• var Xi:integer;• begin• L1:• 按旅客定票要求找到 A[j] ;• P(mutex)• Xi := A[j];• if Xi>=1 • then begin • Xi:=Xi-1; A[j]:=Xi; • V(mutex); 输出一张票; • end;• else begin • V(mutex); 输出票已售完;• end;• goto L1;• end;• •

Page 59: 2.3  进程的同步

59

2.4 经典进程的同步问题2.4.1 生产者消费者问题①一个生产者、一个消费者共享一个缓冲区②一个生产者、一个消费者共享多个缓冲区③多个生产者、多个消费者共享多个缓冲区④多个生产者、多个消费者共享一个缓冲区⑤多个生产者、一个消费者共享多个缓冲区⑥一个生产者、多个消费者共享多个缓冲区

Page 60: 2.3  进程的同步

60

P.V 操作讨论1) 信号量的物理含义: S>0表示有 S 个资源可用 S=0表示无资源可用 S<0则 | S |表示 S 等待队列中的进程个数 P(S): 表示申请一个资源 V(S) 表示释放一个资源。信号量的初值应该大于等于 02) P.V 操作必须成对出现,有一个 P 操作就一定有一个 V 操

作 当为互斥操作时,它们同处于同一进程 当为同步操作时,则不在同一进程中出现 如果 P(S1) 和 P(S2) 两个操作在一起,那么 P 操作的顺序

至 关重要 , 一个同步 P 操作与一个互斥 P 操作在一起时同步 P 操作在互斥 P 操作前

而两个 V 操作无关紧要

Page 61: 2.3  进程的同步

61

一个生产者、一个消费者共享一个缓冲区的解• var B : integer;• empty:semaphore; /* 可以使用的空缓冲区数 */• full:semaphore; /* 缓冲区内可以使用的产品数 */• empty := 1; /* 缓冲区内允许放入一件产品 */• full := 0; /* 缓冲区内没有产品 */• parbegin• Process producer process consumer • begin begin• L1: L2:• Produce a product; P(full);• P(empty); Product:= B;; • B := product; V(empty);• V(full); Consume a product;• Goto L1; Goto L2;• end; end; parend

Page 62: 2.3  进程的同步

62

多个生产者、多个消费者、共享多个缓冲区的解• Var mutex, empty, full : semaphore :=1,n,0; • Buffer:array[0..n-1] of item;• in , out:integer:= 0,0; /* 放入 /取出缓冲区指针 */•  parbegin• proceducer_i consumer_j • Begin • repeat begin• produce a product; L2:P(full);• P(empty); P(mutex);• P(mutex); Product:= Buffer[out];• buffer[in] := product; out:=(out+1) mod n;• in:=(in+1) mod n; V(mutex);• V(mutex); V(empty);• V(full); Consume a product;• until false Goto L2;• end; end;• parend•

Page 63: 2.3  进程的同步

63

苹果桔子问题 桌上有一只盘子,每次只能放

入一只水果;爸爸专向盘子中放苹果 (apple) ,妈妈专向盘子 中 放桔于 (orange) , 一 个儿子专等吃盘子中的桔子,一个女儿专等吃盘子里的苹果

Page 64: 2.3  进程的同步

64

记录型信号量解决苹果桔子问题

plate : integer;sp:semaphore ; /* 盘子里可以放几个水果 */sg1:semaphore; /* 盘子里有桔子 */sg2:semaphore; /* 盘子里有苹果 */sp := 1; /* 盘子里允许放一个水果 */Sg1, := 0; /* 盘子里没有桔子 */sg2 := 0; /* 盘子里没有苹果 */parbeginprocess father begin

L1: 削一个苹果;P(sp);把苹果放入 plate ;V(sg2);goto L1;

end;process mother begin

L2: 剥一个桔子;P(sp);把桔子放入 plate ;V(sg1);goto L2;

end;

process son begin

L3: P(sg1);从 plate 中取桔子;V(sp);吃桔子;goto L3;

end;process daughter begin

L4: P(sg2);从 plate 中取苹果;V(sp);吃苹果;goto L4;

end;parend

Page 65: 2.3  进程的同步

65

2.4.2哲学家吃通心面问题 有五个哲学家围一圆桌旁,桌中央

有一盘通心面,每人面前有一只空盘于,每两人之间放一把叉子。每个哲学家思考、饥饿、然后吃通心面。为了吃面,每个哲学家必须获得两把叉子,且每人只能直接从自己左边或右边去取叉子

Page 66: 2.3  进程的同步

66

Page 67: 2.3  进程的同步

67

哲学家吃通心面问题(3)

var chopstick:array[0..4] of semaphore; chopsticki := 1;cobeginprocess Pi // i=0,1,2,3,4, begin

L1:思考;P(chopstick[i]) ; P(chopstick [(i+1)mod 5]) ; 吃通心面;V(chopstick[i]) ;V(chopstick[(i+1)mod 5]) ;

goto L1; end;coend;

Page 68: 2.3  进程的同步

68

有若干种办法可避免这类死锁 上述解法可能出现永远等待,有若 干种办法可避免死锁:•1) 至多允许四个哲学家同时吃;•2) 奇数号先取左手边的叉子,偶

数号先取右手边的叉子;•3) 每个哲学家取到手边的两把叉

子才吃,否则一把叉子也不取。

Page 69: 2.3  进程的同步

69

2.4.3读者写者问题 有两组并发进程:读者和写者,共享一

个文件 F,要求:• 允许多个读者同时执行读操作• 任一写者在完成写操作之前不允许其它读者或写者工作

•写者执行写操作前,应让已有的写者和读者全部退出

Page 70: 2.3  进程的同步

70

记录型信号量解决读者写者问题 (1)• var Readcount : integer:=0;• W, R: semaphore;• Readcount := 0; /* 读进程计数 */

• W := 1;• R := 1;

Page 71: 2.3  进程的同步

71

记录型信号量解决读者写者问题 (2)• procedure read; procedure write;• begin begin• P(R); P(W);• Readcount := Readcount + 1; 写文件 ;• if Readcount =1 then P(W) ; V(W);• V(R); end; • 读文件;• P(R);• Readcount := Readcount - 1;• if Readcount = 0 then V(W) ;• V(R);• end;

Page 72: 2.3  进程的同步

72

理发师问题• 理发店理有一位理发师、一把理发椅和 n把供等候理发的顾客坐的椅子

• 如果没有顾客,理发师便在理发椅上睡觉

• 一个顾客到来时,它必须叫醒理发师• 如果理发师正在理发时又有顾客来到,

则如果有空椅子可坐,就坐下来等待,否则就离开

Page 73: 2.3  进程的同步

73

记录型信号量解决理发师问题

var waiting : integer; /* 等候理发的顾客数 */ CHAIRS:integer; /* 为顾客准备的椅子数 */ customers, barbers , mutex : semaphore; customers := 0; barbers := 0; waiting := 0; mutex := 1;

Procedure barber;beginwhile(TRUE); /* 理完一人 ,还有顾客吗 ?*/ P(cutomers); /* 若无顾客 ,理发师睡眠 */ P(mutex); /* 进程互斥 */ waiting := waiting – 1; /* 等候顾客数少一个 */ V(barbers); /* 理发师去为一个顾客理发 */ V(mutex); /* 开放临界区 */ cut-hair( ); /* 正在理发 */end;procedure customerbegin P(mutex); /* 进程互斥 */ if waiting<CHAIRS begin /* 看看有没有空椅子 */ waiting := waiting+1; /* 等候顾客数加 1*/ V(customers); /* 必要的话唤醒理发师 */ V(mutex); /* 开放临界区 */ P(barbers); /* 无理发师 , 顾客坐着养神 */ get-haircut( ); /* 一个顾客坐下等理发 */ end V(mutex); /* 人满了 ,走吧 !*/end;

Page 74: 2.3  进程的同步

74

哲学家吃通心面问题的一种正确解

var forki :array[0..4] of semaphore; forki := 1;parbeginprocess Pi //* i=0,1,2,3 */begin

L1:思考;P(fork[i]) ; //*i=4,P(fork[0])*/P(fork[i+1] mod5)//*i=4,P(fork[4])*/吃通心面;V(fork[i]) ;V(fork([i+ 1] mod 5) ;

goto L1; end;parend;