软件同步机制-Peterson解决方案 简单讲解
Peterson 解决方案是用来处理两个进程互斥访问临界区的问题,临界区就是一段不允许其他进程同时进入执行的代码区域 。
共享变量
int turn = 0;
:这个变量用来记录轮到哪个进程进入临界区。它就像一个指示牌,告诉进程现在该谁 “上场” 了。初始值为 0 ,可以理解为一开始默认先让某个进程(比如进程 0 )有优先进入的机会。turn == i;
:这是一个判断条件,当turn
的值等于进程编号i
时,意味着当前进程Pi
可以进入临界区。j = 1 - i;
:因为是两个进程,i
取值为 0 或 1 ,通过这个计算得出另一个进程的编号。比如i = 0
时,j = 1
,代表另一个进程 。boolean flag[2];
:这是一个布尔数组,有两个元素。flag[0]
和flag[1]
,分别对应两个进程。flag [0] = flag [1] = false;
:表示一开始两个进程都没有准备进入临界区。flag [i] = true ;
:当进程Pi
想要进入临界区时,会把自己对应的flag[i]
设为true
,就像举个牌子说 “我准备进入临界区啦” 。
进程 Pi 的执行流程
- 准备阶段:
flag [i]:= true;
:进程Pi
把自己的flag
标记设为true
,宣告自己想进入临界区。turn = j;
:进程Pi
把turn
设为另一个进程Pj
的编号,这是一种 “礼让” 行为,意思是 “我虽然想进,但也先看看对方要不要进” 。while (flag [j] and turn = j);
:进程Pi
会检查另一个进程Pj
的状态。如果Pj
也想进入临界区(flag[j]
为true
) ,而且现在轮到Pj
(turn = j
) ,那进程Pi
就会在这个循环里等待。就好比在门口排队,得等前面的人进去或者轮到自己才能进 。
- 进入临界区:当等待条件不满足了,说明
Pj
不想进或者轮到自己了,进程Pi
就可以进入临界区执行关键代码 。 - 离开临界区:
flag [i] = false;
,进程Pi
执行完临界区的代码后,把自己的flag
标记设为false
,表示 “我已经从临界区出来啦” 。 - 剩余区操作:进程
Pi
去执行其他非关键代码部分,也就是剩余区的操作 ,然后又会循环回到准备进入临界区的步骤,不断重复这个过程 。
Peterson 解决方案满足了
互斥(同一时刻只有一个进程能进入临界区 )、
进展(只要有进程需要进入临界区,就不会出现所有进程都无法进入的死锁情况 )、
有限等待(一个进程请求进入临界区后,在其他进程有限次进入临界区后,该进程一定能进入 )这三个需求,有效解决了两个进程的临界区问题 。