1、3.10 设在书 3.6节中所描述的生产者-消费者问题中,其缓冲部分为m个长度相等的有界缓冲区组成,且每次传输数据长度等于有界缓冲区长度以及生产者和消费者可对缓冲区同时操作。重新描述发送过程deposit(data)和接收过程remove(data)。,作业中主要问题: 1、设第1块缓冲区的公用信号量为mutex1 2、mutexi ;mutex ti ; mutex n 3、P(avail)P(mutexi ) V(full)V(mutexi ),分析: 1、本题所描述的生产者-消费者问题中,“其缓冲部分为m个长度相等的有界缓冲区组成,且每次传输数据长度等于有界缓冲区长度”,与教材中3.6节
2、(P62)问题有所不同。 (1)教材中3.6节问题中,一次从有界缓冲区中取一个单元; (2)这里,一次从m个有界缓冲区中取一个缓冲区。,2、本题所描述的生产者-消费者问题中,“生产者和消费者可对缓冲区同时操作”,与教材中3.6节(P62)问题有所不同。 (1)教材中3.6节问题中,由于有界缓冲区是临界资源,因此,各生产者进程和各消费者进程之间必须互斥执行。 (2)这里,生产者和消费者之间不需要互斥。 (3)生产者和生产者之间?消费者和消费者之间?,解:首先,可以看到,本问题是一个同步问题。即生产者和消费者之间满足如下条件: (1) 消费者想接收数据时,有界缓冲区中至少有一个缓冲区是满的; (2
3、) 生产者想发送数据时,有界缓冲区中至少有一个缓冲区是空的。,其次,虽然生产者和消费者之间不需要互斥,但在生产者(消费者)之间,由于有界缓冲区是临界资源,因此,各生产者(消费者)进程之间必须互斥执行。 由上分析,设公用信号量mutex1用来保证生产者进程间的互斥,公用信号量mutex2用来保证消费者进程间的互斥, mutex1 和mutex2初值均为1;,设信号量avail为生产者进程的私用信号量,表示空缓冲区数目,初值为m; 设信号量full为消费者进程的私用信号量,表示非空缓冲区数目,初值为0; 从而有:,生产者进程 deposit(data):begin(avail)(mutex1)送数
4、据入某空缓冲区( mutex1 )( full)end,消费者进程 remove(data):begin(full)(mutex2)取某缓冲区中数据( mutex2 )( avail)end,3.11 两进程PA,PB通过两FIFO缓冲区队列连接(如图),每个缓冲区长度等于传送消息长度。进程PA,PB之间的通信满足如下条件:(1) 至少有一个空缓冲区存在时,相应的发送进程才能发送一个消息。 (2) 当缓冲队列中至少存在一个非空缓冲区时,相应的接收进程才能接收一个消息。 试描述发送过程send(i,m)和接收过程receive(i,m)。这里i代表缓冲队列。,作业中主要问题: 1、bufempt
5、y0= bufempty1=n 2、local xbuf i (x)buf i (x)m 3、算法格式:缩进;分号 4、教材P61,分析: 1、本题所描述问题中(设上面的缓冲队列为0,下面的缓冲队列为1,即i的值为0和1), (1)PA从队列1中接收数据时,要求至少有一个缓冲区是非空的;向队列0中发送数据时,要求至少有一个缓冲区是空的;,分析: (2)PB从队列0中接收数据时,要求至少有一个缓冲区是非空的;向队列1中发送数据时,要求至少有一个缓冲区是空的。 2、因为是FIFO缓冲区队列,所以对缓冲区队列的操作不需要互斥。 3、由于PA和PB的对称性,对i要进行一定处理,解:首先,可以看到,本问
6、题存在同步关系,即PA和PB之间存在着同步关系。 (1) 设ni为缓冲队列i中缓冲区的个数。 (2)设SM(i) 为发送进程的私用信号量,表示缓冲队列i中空缓冲区的个数,其初值为 ni 。 (3)设RM(i) 为接收进程的私用信号量,表示缓冲队列i中满缓冲区的个数,其初值为0。,(2)设SM(i) 为发送进程的私用信号量,表示缓冲队列i中空缓冲区的个数,其初值为 ni 。 (3)设RM(i) 为接收进程的私用信号量,表示缓冲队列i中满缓冲区的个数,其初值为0 。 (4) 进程PA或PB调用过程receive(i,m)将消息m从缓冲队列i读往自己的数据区;调用过程send(i,m)将消息m送往缓
7、冲队列i。,(4) 进程PA或PB调用过程receive(i,m)将消息m从缓冲队列i读往自己的数据区;调用过程send(i+1 mod 2,m)将消息m送往缓冲队列i+1 mod 2。,send(i,m):begin建立消息m(SMi)将消息m送入消息缓冲队列i(RMi)end,可描述过程send(i,m) 和receive(i,m)如下:,receive (i,m):begin(RMi)从消息缓冲队列i中接收消息m,并送入接收进程的数据区(SMi)end,可描述过程send(i,m) 和receive(i,m)如下:,PA:(i=0)cobeginsend(i,m) receive(i+1
8、 mod 2,m) coend,PA和PB的描述如下:,PB:(i=1)cobeginsend(i,m) receive(i+1 mod 2,m) coend,PA:(i=0)cobeginsend(0,m) receive(1,m) coend,PA和PB的描述如下:,PB:(i=1)cobeginsend(1,m) receive(0,m) coend,3.14 设有5个哲学家,共享一张放有五把椅子的桌子,每人分得一把椅子。但是,桌子上总共只有5支筷子,在每人两边分开各放一支。哲学家们在肚子饥饿时才试图分两次从两边拾起筷子就餐。 条件: (1) 只有拿到两支筷子时,哲学家才能吃饭。 (2)
9、 如果筷子已在他人手上,则该哲学家必须等待到他人吃完之后才能拿到筷子。 (3) 任一哲学家在自己未拿到两支筷子吃饭之前,决不放下自己手中的筷子。,试: (1) 描述一个保证不会出现两个邻座同时要求吃饭的通信算法。 (2) 描述一个既没有两邻座同时吃饭,又没有人饿死(永远拿不到筷子)的算法。 (3) 在什么情况下,5 个哲学家全部吃不上饭?,哲学家就餐问题:,作业中主要问题: 1、信号量的说明 2、分奇偶; 3、“任一哲学家拿到一支筷子,就已经阻止了邻座的哲学家吃饭”,作业中主要问题: 4、 send(i);(与c 5、 P(ci,ci+1 mod 5) 或P(ci),P(ci+1 mod 5)
10、 6、“看到右侧筷子不可用,又放下左侧筷子” 7、 5个哲学家同时拿起筷子 8、如果出现死锁,则5个哲学家都吃不上饭 9、在本题(1)中, 5个哲学家都吃不上饭,解:显然,5支筷子都是临界资源,五个哲学家philosopher(i)取用筷子就餐时要进行互斥。 (1) 要保证不会出现两个邻座同时要求吃饭,就要求各philosopher(i)按一定的顺序取筷子。设公用信号量forki用于philosopher(i)取用筷子就餐时的互斥,其初值均为1。这里i的取值为04,并且都是先取右边的筷子,再取左边的筷子。当i=4时,左边的筷子是i+1 mod 5,即0。,算法如下(i=0,1,2,3,4):
11、philosopher ( i )begin/ Think/ EatP( forki )P( fork i+1 mod 5 )eat ()V( fork i+1 mod 5 ) V( forki )end,(3) 从算法中可以看到,当每位philosopher(i) 都取到了左边的筷子,然后试图取右边的筷子时,会出现5位哲学家都吃不上饭的情形。即出现饿死现象。,philosopher ( i )beginP( forki )P( fork i+1 mod 5 )eat ()V( fork i+1 mod 5 ) V( forki )end,(2) 要保证不出现既没有两邻座同时吃饭,又没有人饿死
12、(永远拿不到筷子)的情形,只要某位philosopher(i)按相反的顺序取筷子即可。设公用信号量forki用于philosopher(i)取用筷子就餐时的互斥,其初值均为1。这里i的取值为04,规定philosopher(4)先取左边的筷子,再取右边的筷子。,算法如下(i=0,1,2,3): philosopher ( i )begin/ Think/ EatP( forki )P( fork i+1 )eat ()V( fork i+1 ) V( forki )end,philosopher (4)begin/ Think/ EatP( fork0 )P( fork 4 )eat ()V(
13、 fork 4 ) V( fork0 )end,补:荷兰科学家E.W.Dijkstra在1968年发表的一篇论文中提出了三种用来解决临界区互斥问题的算法。这三种算法正确吗?若不正确,请分别说明为什么不正确。即指出在什么情况下不正确。,(a),proc( int i = 0) while (TRUE) compute ;while (turn != 0 ) ;critical section ;turn = 1; ,proc( int i = 1) while (TRUE) compute ;while (turn != 1 ) ;critical section ;turn = 0; ,sha
14、red int turn ; turn = 1 ; fork(proc, 1, 0) ; fork(proc, 1, 1) ;,(b),proc(int i) while (TRUE) compute ;while ( flag (i+1) mod 2 ) ;flag i = TRUE ;critical section ;flag i = FALSE ; shared boolean flag2 ; flag0 = flag1 = FALSE ; fork(proc, 1, 0) ; fork(proc, 1, 1) ;,(c),proc(int i) while (TRUE) compute ;flag i = TRUE ;while ( flag (i+1) mod 2 ) ;critical section ;flag i = FALSE ; shared boolean flag2 ; flag0 = flag1 = FALSE ; fork(proc, 1, 0) ; fork(proc, 1, 1) ;,