首页 > 试题广场 >

则并发执行进程P 0 和P1时产生的情况是()

[单选题]


进行P 0 和P1的共享变量定义及 若进程 P0和P1访问临界资源的类C伪代码实现如下
boolean flag[2]; 
int turn=0;  
flag[0]=false; 
flag[1]=false;  
若进程P0和P1访问临界资源的类C代码实现如下:
Void P0 ()   //进程P0 {  
	while (TURE){  
		Flag[0]=TURE;
		turn=1;  
		While (flag[1]&&(turn==1));          
		临界区;  
		Flag[0]=FALSE; 
	} 
}  
Void P1 ()   //进程P1 {  
	while (TURE){  
		Flag[1]=TURE;
		turn=0;  
		While (flag[0]&&(turn==0));        
			临界区;  
		Flag[1]=FALSE; 
	} 
}


则并发执行进程P 0 和P1时产生的情况是()
  • 不能保证进程互斥进入临界区,会呈现"饥饿"现象
  • 不能保证进程互斥进入临界区,不会呈现"饥饿"现象
  • 能保证进程互斥进入临界区,会呈现"饥饿"现象
  • 能保证进程互斥进入临界区,不会呈现"饥饿"现象
1. 代码满足互斥和有限等待
互斥:
flag[0]和flag[1]总是有先后顺序的,无论谁先执行,第二个的while()循环都通过不了!

有限等待(不会死锁):
假如P0执行到while0(),P1要么没有执行:while0()因为flag[1] = 0而通过;
P1要么执行了,但是P1一旦执行flag[1] = 1,也会执行ture = 0,所以还是拦不住while0();


2. 互斥和有限等待的理解
假如只有一个flag,是无法实现互斥的,比如我们最容易理解的:
if(!busy) {
    busy = true;
    临界区
    busy = false;
}
多个线程可以同时达到临界区之前的busy = true,并且顺利通过。

想要实现一个锁,要保证互斥,这个只需要flag[2]就够了:
Void P0 ()  //进程P0 {  
    while(TURE){  
        flag[0]=TURE;
        While (flag[1]);          
        临界区;  
        flag[0]=FALSE; 
    } 
}  
Void P1 ()  //进程P1 {  
    while(TURE){  
        flag[1]=TURE;
        While (flag[0]);        
            临界区;  
        Flag[1]=FALSE; 
    } 
}
通过flag0和flag1,进入临界区之前互相给对方上锁,完成互斥:
P0和P1同时达到while(),但是无法全部顺利通过!

但是,也要保证不要死锁,即保证不能所有临界区都black在while():
上面的while()内只判断flag,flag可以同时为1,所以会死锁!

所以这里增加了变量true,true只对对方进程起作用,对自己,就好像没有一样:
turn=1;  
While (flag[1]&&(turn==1)); 
true的作用就是给对方解锁。
所以皮特森算法就完成了互斥和有限的锁!


3. 打个比方:
一间屋子有AB两个门 —— 临界区及入口;
有ab两个人,分别从AB门进入 —— 进程;
ab连个人分别有自己的锁,可以锁对方的门 —— flag0和flag1的作用;
有一盏灯,挂在墙上,只能对着A门或者B门,只有在(灯打开 && ab看到自己门上有锁)的时候,才会在门口等待 —— true的作用;

a来到:
给b上锁 -> 把灯对着A门 -> 看一下有没有锁 -> 有就等,没有就进;
假如a还没有来得及看锁,b就把灯转过去对着自己门,那A看不到锁,就会进门!
(b当然会看到自己门上有把锁,a放的)
编辑于 2021-12-18 14:16:40 回复(0)
没错吧,while循环那不是有分号吗,条件成立不是进入临界区而是循环等待
发表于 2017-11-04 13:30:15 回复(0)
这道题是想考皮特森算法吧。但是代码有有点问题。进程P1的代码中,turn应当赋值为0。
代码如下:
boolean flag[2]; 
	int turn=0;  
	flag[0]=false; 
	flag[1]=false;  
	
	void P0 ()   //进程P0 {  
	    while (TURE){  
	        Flag[0]=TURE;
	        turn=1;  
	        While (flag[1]&&(turn==1));          
	        临界区;  
	        Flag[0]=FALSE; 
	    } 
	} 
	void P1 ()   //进程P1 {  
	    while (TURE){  
	        Flag[1]=TURE;
	        turn=0;//这里应该赋值为0  
	        While (flag[0]&&(turn==0));          
	        临界区;  
	        Flag[1]=FALSE; 
	    } 
	}

编辑于 2017-07-30 09:07:08 回复(5)
p1 trun==0才会被执行呀   这个条件好像永远不会满足
发表于 2016-12-29 20:34:06 回复(2)

turn理解为可以进入临界区的进程才对吧?

发表于 2019-10-07 19:55:16 回复(0)
这个题目有问题,首先,若按照题目写的程序,p0先上CPU,进入临界区后,turn=1,flag[0]=true,flag[1]=false,p1上CPU,依然可以进临界区,没有解决互斥问题。若p0改为turn=0,这个是可以解决的,也就是Peterson软件解法。
发表于 2017-03-03 00:12:40 回复(1)
这个题目。。
发表于 2023-10-02 01:08:46 回复(0)
感觉这里的关键是注意到turn这个变量
发表于 2023-09-25 13:00:15 回复(0)
精彩
发表于 2021-11-25 13:59:23 回复(0)

皮特森算法

发表于 2020-03-11 15:52:32 回复(0)
皮特森算法,两个flag保证进程之间的互斥,但是可能存在死锁,互相阻塞的情况,这个时候就采用turn来决定执行的进程
发表于 2019-07-01 22:25:41 回复(0)
皮特森算法,既互斥也不会饥饿
发表于 2019-02-25 00:07:33 回复(0)
题目没错  while成立就进入了 循环等待
发表于 2018-08-14 21:07:10 回复(0)
flag[i]表示i进程想要进入临界区,turn表示该进程的ID号。
While (flag[1]&&(turn==1)); 当i进程想要访问临界区时,让其循环等待,j进程此时就可以进入临界区了,实现了互斥访问。
发表于 2018-07-12 17:43:25 回复(0)
没错
发表于 2018-05-09 10:34:28 回复(0)
个人觉得题目是不是出错了,进程P1根本没办法进入临界区
发表于 2017-03-24 18:47:50 回复(0)
我觉得应该是C啊,两个进程都进不了临界区吧

发表于 2017-03-02 10:46:42 回复(0)