Dekker算法初步设想【保证了互斥】:让两个进程共享一个全局变量turn,【其初值为0或1】。如果turn==i,那么进程Pi允许在其临界区内执行。
—为了控制两个进程互斥进入临界区,可以让两个进程轮流进入临界区。
—当一个进程正在临界区执行时,另一个进程就不能进入临界区,而在临界区外等待。
1.为何是“强制交替”?
Turn=0时,无论CS空闲与否,即使P1就绪想要进入CS也【不会成功】,必须等待P0进入CS执行,退出后才能进入CS。
【关键】turn=0时P1:while(turn!=1);会一直陷入循环【忙等】,直至P0运行一次,turn值改为1,P1进程才可以运行。(一般turn=0是P1执行的结果,即P1执行后P1不能再次执行,必须换到P0执行。所以是“强制交替”)
2.为何不满足“前进要求”,任何进程在CS 区内外失败,其他进程都可能因为等待使用CS而无法向前推进?
可能恰恰是因为“强制交替”,假若P0和P1两个进程交替,P0进程如果没有修改turn=1就死了,那么P1就永远无法运行。
Dekker算法-改进一:
【初步设想】让两个进程共享一个全局变量turn,【其初值为0或1】。如果turn==i,那么进程Pi允许在其临界区内执行。
【改进一】使用全局共享数组flag标志CS状态:
flag[0]或flag[1]=true:表示P0或P1占用CS,
flag[0]或flag[1]=false:表示CS空闲。
1.进程在CS内失败?什么意思?
【未解决】2017.11.29
2.不能实现互斥,P0和P1可能同时进入临界区。【初步设想是实现了互斥的】
Dekker算法-改进二【改为先置标志位】:
Dekker算法-【最终成功版】:
flag[2]用来表示是否想要使用关键区,turn用来表示具有访问权限的进程ID。(重点看注释,通过注释,挺好理解的哟~)
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#define true 1
#define false 0
typedef int bool;
bool flag[2];
int turn;
void visit(int num)
{
sleep(1);
printf("P%d is visting\n",num);
}
void P0()
{
while(true)
{
flag[0] = true;//P0想使用关键区。
while(flag[1])//检查P1是不是也想用?
{
if(turn == 1)//如果P1想用,则查看P1是否具有访问权限?
{
flag[0] = false;//如果有,则P0放弃。
while(turn == 1);//检查turn是否属于P1。
flag[0] = true;//P0想使用。