modify some mistakes.

This commit is contained in:
Shine wOng
2019-09-22 21:05:26 +08:00
parent 3cadbfcf07
commit 8a52f58f8d

View File

@@ -51,7 +51,7 @@ flag[pid] = false;
然后看了看向勇老师的网课,他说所有可能进入临界区的进程是排成了一个环。想要进入临界区的进程只需要等待介于`turn`和自己之间的进程。进程退出临界区时,将`turn`设置为下一个请求进入的进程。整体的流程如下图所示:
![nproc_mutex](nproc_mutex.png)
![nproc_mutex](images/nproc_mutex.png)
因此,我就根据这个简单的描述修改了上面第一种尝试的代码,形成了下面的代码:
@@ -77,7 +77,7 @@ flag[pid] = false;
看起来这种实现方法似乎规避了第一次尝试的不足,因为总存在第一个离`turn`最近的请求进程,它只需要等待`turn`进程即可,不可能出现多个想要进入临界区的进程互相等待的情况,并且如果`turn`进程并没有请求进入临界区,离`turn`最近的进程可以直接通过循环进入临界区,满足了`空闲则入`原则。
但是通过深入的分析,我们可以构造出一种特殊情况。当前拥有`turn`的进程没有请求进入临界区,距离`turn`为1的进程没有请求临界区距离`turn`为3的进程发出了请求因此它进入`for`循环判断在`turn`和它之间的进程是否还有发出请求的。然后这个循环还没有结束,刚刚判断完了距离`turn`为1的进程就发生了进程的调度。此时距离`turn`为1的进程发出了进入临界区的请求,这样,这两个进程就同时进入临界区了,就违背了`忙则等待`原则。
但是通过深入的分析,我们可以构造出一种特殊情况。当前拥有`turn`的进程没有请求进入临界区,距离`turn`为1的进程没有请求临界区,距离`turn`为3的进程发出了请求因此它进入`for`循环判断在`turn`和它之间的进程是否还有发出请求的。然后这个循环还没有结束,刚刚判断完了距离`turn`为1的进程就发生了进程的调度。此时距离`turn`为1的进程发出了进入临界区的请求这样这两个进程就同时进入临界区了就违背了`忙则等待`原则。
## `eisenberg`算法
@@ -134,7 +134,7 @@ CYCLE2:
/* we're finished now */
flags[i] := IDLE;
/* REMAINDER Section */
/* REMAINDER Section */
```
可以看得到,这个算法也太复杂了,下面直接给出对该算法的分析。
@@ -143,10 +143,10 @@ CYCLE2:
`CYCLE1`中的操作与我们第二次尝试的`for`循环一致,即判断从`turn`到当前进程之间是否存在请求进程,若存在,则不断循环`CYCLE1`,直至不存在这样的进程,将当前进程标记为`ACTIVE`。可以看出,所有标记为`ACTIVE`的进程,在循环中都判断自己是距离`turn`最近的请求进程,但是由于进程的调度,这样的进程仍然有多个,而这正是导致我们第二次尝试失败的原因。
`CYCLE2`中,对所有`ACTIVE`的进程做进一步的判断,主要操作就是判断除了当前进程以外,是否还存在其他`ACTIVE`的进程。需要注意的是,这里是对所有其他进程做判断,而不仅限于判断从`turn`到当前进程。
`CYCLE2`中,对所有`ACTIVE`的进程做进一步的判断,主要操作就是判断除了当前进程以外,是否还存在其他`ACTIVE`的进程。需要注意的是,这里是对所有其他进程做判断,而不仅限于判断从`turn`到当前进程。可以看到,`CYCLE2`对应了我们的第一次尝试。
进入临界区的条件是,当前进程是唯一的`ACTIVE`进程,并且当前进程获得了`turn`,或者获得`turn`的进程处于`IDLE`状态。否则,退回到`CYCLE1`重新进行上面的判断。
首先证明,`eisenberg`算法是满足`忙则等待`原则的,这是通过`CYCLE2`来实现的。在第一次尝试中已经说明过,对所有进程做遍历并且保证当前进程是唯一的请求进程或者`ACTIVE`进程是一种更强的互斥条件,它甚至会导致`空闲则入`原则的不满足。
下面说明一定会有进程可以进入临界区,即`空闲则入`原则是满足的。设一次循环中,所有`ACTIVE`状态的进程中,距离`turn`最近的进程为`pid_min`,距离`turn`最远的进程为`pid_max`。在`CYCLE2`中,由于同时存在多个`ACTIVE`进程,所有这些进程都会重新进入`WAITING`状态并且退回到`CYCLE1`。第二次循环,根据`CYCLE1`的性质,这些进程中只有`pid_min`可以通过`CYCLE1`进入`ACTIVE`状态,此时进入`ACTIVE`状态的进程至多只有`pid_min - turn`个。这样,在每次循环以后,可以进入`ACTIVE`状态的进程数量是递减的,最终只会有一个进程可以通过`CYCLE1`进入`ACTIVE`状态,并且获得临界区的访问权限。
下面说明一定会有进程可以进入临界区,即`空闲则入`原则是满足的。设一次循环中,所有`ACTIVE`状态的进程中,距离`turn`最近的进程为`pid_min`,距离`turn`最远的进程为`pid_max`,这样`ACTIVE`状态的进程至多有`pid_max - turn`。在`CYCLE2`中,由于同时存在多个`ACTIVE`进程,所有这些进程都会重新进入`WAITING`状态并且退回到`CYCLE1`。第二次循环,根据`CYCLE1`的性质,这些进程中只有`pid_min`可以通过`CYCLE1`进入`ACTIVE`状态,此时进入`ACTIVE`状态的进程至多只有`pid_min - turn`个。这样,在每次循环以后,可以进入`ACTIVE`状态的进程数量是递减的,最终只会有一个进程可以通过`CYCLE1`进入`ACTIVE`状态,并且获得临界区的访问权限。