在Peterson算法中,如果我们将`turn`变量切换到当前进程而不是其他进程会怎样?

问题描述 投票:0回答:1

在 Peterson 算法中,进程将

turn
变量切换到 other 进程。

但是,我想知道为什么我们不将turn变量切换到current进程中,如下所示:

void process0() {
    flag[0] = 1; // Process 0 wants to access the critical section
    turn = 0; // It's Process 0's turn to access the critical section
    while (flag[1] && turn == 1); // If Process 1 wants to access the critical section and it IS Process 1's turn, then Process 0 should wait
    // Process 0 accesses the critical section
    flag[0] = 0; // Process 0 quits the critical section
    // Remaining codes
}

void process1() {
    flag[1] = 1; // Process 1 wants to access the critical section
    turn = 1; // It's Process 1's turn to access the critical section
    while (flag[0] && turn == 0); // If Process 0 wants to access the critical section and it IS Process 0's turn, then Process 1 should wait
    // Process 1 accesses the critical section
    flag[1] = 0; // Process 1 quits the critical section
    // Remaining codes
}

似乎总有一个进程能够访问临界区,并且也只有一个进程可以访问临界区。那么我们为什么不将turn变量切换为当前进程号呢?

我尝试过使用这个Python代码:

import threading, random


END_POSSIBILITY = 0.001 # The possibility that one process finishes running

flag = [False, False]
turn = 0

class CriticalSection:
    def __init__(self) -> None:
        self.visitor = -1

    def visit(self, visitor: int) -> None:
        if self.visitor == -1:
            self.visitor = visitor
        else:
            raise Exception(f"CRITICAL SECTION IS ALREADY BEING VISITED BY PROCESS {self.visitor}, CANNOT BE VISITED BY {visitor}!!!")
        
    def unvisit(self) -> None:
        self.visitor = -1


critical_section = CriticalSection()

def process0():
    global turn
    
    while True:
        flag[0] = True

        turn = 0

        while flag[1] and turn == 1:
            pass

        critical_section.visit(0)

        flag[0] = False
        critical_section.unvisit()

        if (random.random() <= END_POSSIBILITY):
            break


def process1():
    global turn
    
    while True:
        flag[1] = True

        turn = 1

        while flag[0] and turn == 0:
            pass

        critical_section.visit(1)

        flag[1] = False
        critical_section.unvisit()

        if (random.random() <= END_POSSIBILITY):
            break


thread0 = threading.Thread(target=process0)
thread1 = threading.Thread(target=process1)

thread0.start()
thread1.start()

我多次运行这段代码,一切正常。

multithreading multiprocessing operating-system
1个回答
0
投票

假设操作顺序如下。

P1 执行时 P2 停止:

flag[0] = 1;
turn = 0;
while (flag[1] && turn == 1); // terminates immediately because turn == 0
// critical section

当 P1 处于临界区时,P2 开始执行:

flag[1] = 1;
turn = 1;
while (flag[0] && turn == 0); // terminates immediately because turn == 1
// critical section

现在两个进程同时处于临界区。

本质上,在您的版本中,任何一个进程现在都可以声明轮到自己了,而完全忽略另一个进程是否位于临界区的中间。

© www.soinside.com 2019 - 2024. All rights reserved.