实现进程互斥的方法

1软件方法:

1.1单标志法

/* PROCESS 0 */
while(turn != 0);
/* critical section */
turn = 1;

/* PROCESS 1 */
while(turn != 1);
/* critical section */
turn = 0;

特点:1)进入临界区之前先检查turn,如果等于进程号,就可以进入临界区,否则循环等待,因此可以实现互斥;2)等待期间会耗费处理器时间;3)两个进程交替使用处理器,执行速度取决于慢的进程;4)如果一个终止(无论是在临界区内还是临界区外),另一个会被永远阻塞。

1.2双标志先检查法

/* PROCESS 0 */
while(flag[1]);
flag[0] = true;
/* critical section */
flag[0] = false;

/* PROCESS 1 */
while(flag[0]);
flag[1] = true;
/* critical section */
flag[1] = false;

特点:1)进入临界区之前先检查另一个进程的flag,直到该flag==false,然后设置本进程的flag置为true,接着进入临界区,出了临界区再把本进程的flag置为false;2)如果一个进程出了临界区且置flag为false后终止,,则另一个进程不会被阻塞;3)如果一个进程在临界区内终止,或者在置flag为true且进入临界区之前终止,则另一个进程会永久阻塞;4)两个进程还可能同时进入临界区,导致互斥失败。

1.3双标志后检查法

/* PROCESS 0 */
flag[0] = true;
while(flag[1]);
/* critical section */
flag[0] = false;

/* PROCESS 1 */
flag[1] = true;
while(flag[0]);
/* critical section */
flag[1] = false;

特点:1)进入临界区之前先把本进程的flag置为true;然后再检查另一个进程的flag,直到该flag==false,接着进入临界区,出了临界区再把本进程的flag置为false;2)如果一个进程出了临界区且置flag为false后终止,则另一个进程不会被阻塞;3)如果一个进程在临界区内终止,或者在置flag为true之后且进入临界区之前终止,则另一个进程会永久阻塞;4)保证了互斥,但可能造成死锁。

1.4Dekker算法

void P0(){
    while(true){
        flag[0] = true;
        while(flag[1]){
            if(turn == 1){
                flag[0] = false;
                while(turn == 1);
                flag[0] = true;
            }
        }
        /* critical section */
        turn = 1;
        flag[0] = false;
    }
}

void P1(){
    while(true){
        flag[1] = true;
        while(flag[0]){
            if(turn == 0){
                flag[0] = false;
                while(turn == 0);
                flag[1] = true;
            }
        }
        /* critical section */
        turn = 0;
        flag[1] = false;
    }
}

特点:先置自己的flag为true,表明想要进入临界区的意愿,然后检查另一进程的flag,如果另一个进程也想进入临界区,则找第三方和事佬看一下turn——如果轮到其他进程,只能礼让,把自己的flag置为false,让另一个进程跳出循环进入临界区;如果轮到自己, 则等待对方把flag置为false,然后跳出循环进入临界区,出了临界区再把turn让给别人,同时置自己的flag为false。

1.5Peterson算法

void P0(){
    while(true){
        flag[0] = true;
        turn = 1;
        while(flag[1] && turn==1);
        /* critical section */
        flag[0] = false;
    }
}

void P1(){
    while(true){
        flag[1] = true;
        turn = 0;
        while(flag[0] && turn==0);
        /* critical section */
        flag[1] = false;
    }
}

特点: 先置自己的flag为true,表明想要进入临界区的意愿,但是先礼让其他进程,主动把turn让给其他人——如果其他进程刚好想进入临界区,上门的好事不要白不要,赶紧跳出循环进入临界区;如果其他进程不想进入临界区,则跳过循环进入临界区,出了临界区置自己的flag为false。

2硬件方法

2.1关中断

2.2TestAndSet指令

bool TestAndSet (bool &lock){
    bool old;
    old = lock;
    lock = true;
    return old;
}

while TestAndSet(&lock);
/* critical section */
lock = false;

exchange指令

void Swap (bool &a, bool &b){
    bool temp;
    temp = a;
    a = b;
    b = temp;
}

lock = false;    //全局共享变量
key = true;    //局部变量
while(key)
    Swap(lock, key);
/* critical section */
lock = false;

猜你喜欢

转载自blog.csdn.net/Lee_01/article/details/82154731