Petetson算法解决进程竞争问题

来源:互联网 发布:天津网络作家排行榜 编辑:程序博客网 时间:2024/06/13 21:40

因进程竞争共享内存、共享文件以及任何共享资源引起的竞争而产生的莫名其妙的问题。

解决竞争的办法需要的是互斥(mutual exclusion),即以某种手段确保当一个进程在使用一个共享变量或者文件时,其它进程不能做同样的操作。

避免竞争的问题也可以用一种抽象的方式进行描述。一个进程的一部分时间做内部计算或另外一些不会引起竞争条件的操作。在某些时候进程可能需要访问共享内存或共享文件,或执行另外一些导致竞争的操作。我们把对共享内存进行访问的程序片段称作临界区域(critical region)或者临界区(critical section)。如果我们能够安排适当,使得两个进程不可能同时处于临界区中,就能够避免竞争条件。尽管这样避开了竞争条件,但它还不能够保证使用共享数据的并发进程能够正确和高效地进行协作。下面给出了,对于一个好的

解决方案,需要满足以下4个条件:

1)任何两个进程不能同时处于其临界区

2)不应对CPU的速度和数量做任何假设

3)临界区外运行的进程不得阻塞其它进程

4)不得使进程无限期等待进入临界区

解决方案之Peterson互斥算法

#define FALSE   0#define TRUE1#define N2//进程数量int turn;//现在轮到谁int interested[N];//所有值初始化为0void enter_region(int process)//进程是0或1{int other;//其它进程号other = 1-process;//另一方进程interested[process] = TRUE;//表明所感兴趣的turn = process;//设置标志while (turn == process && interested[other] == TRUE)//;//空语句}void leave_region(int process)//进程:谁离开?{interested[process] = FALSE;//表示离开临界区}/*************完成互斥的Peterson算法分析*****************//*    在使用共享变量(即将进入临界区)之前,各个进程使用其进程号0或1作为参数来调用enter_region。该调用在需要时将使进程等待直到能安全地进入临界区。在完成对共享变量的操作之后,进程将调用leave_region,表示操作已完成,若其他的进程希望进入临界区,则现在就可以进入。    现在来看看这个方案是如何工作的。一开始,没有任何进程进入临界区中,现在进程0调用enter_region。它通过设置其数组元素和将turn置为0,表示希望进入临界区。由于进程1并不想进入临界区,所以enter_region很快就会返回。如果进程1现在调用enter_region,进程1将在此处挂起直到interested[0] 变为FALSE,该事件只有在进程0调用leave_region退出临界区时才会发生,此时进程1才能进入临界区。    现在考虑两个进程几乎同时调用enter_region的情况。它们将自己的进程号存入turn,但只有后被保存进去的进程号才有效,前一个因重写而丢失。假设进程1是后存入的,则turn为1.当两个进程都运行到while语句时,进程0将循环0次并进入临界区,而进程1则将不停地循环且不能进入临界区,直到进程0退出临界区为止*/

Peterson解法是正确的,但它有忙等待的缺点。解法的本质是这样的:当一个进程进入临界区时,首先检查是否允许进入,若不允许,则该进程将原地等待,直到允许为止。

这种方法不仅浪费了CPU时间,而且还可能引起预想不到的结果。考虑一台计算机的两个进程,H进程的优先级较高,L优先级较低。调度规则规定,只要H处于就绪它就可以运行。某一时刻L处于临界区中,此时H变到就绪态,准备运行(例如,一条I/O操作结束)。现在H开始忙等待,但由于当H就绪时L不会被调度,也就无法离开临界区,所以H就永远等待下去。这种情况有时称作优先级反转问题(priority inversion problem)。

0 0
原创粉丝点击