Person‘s solution 是用来一种基于软件的解决关键区域问题的算法(critical-section).
它并非完美的,有可能不正确地工作。而且是限制解决两个进程同步的问题。
但是它很简单,很原始,学习起来也是很轻松的。
代码如下:
do { flag[i] = true; turn = j; while (flag[j] && turn == j); critical section flag[i] = false; remainder section } while (true);
flag[]其实是一个2个变量的数组。这里的i标志一个进程,而j标志另一个进程。
critical section代表是需要互斥进入的一个区间,比如需要修改一些关键的共享数据,这个时候不能让两个进程同时修改,否则就会出现不可预知的结果了。记得好像见过阿里巴巴笔试有这样的题目。
有remainder section并非关键区域,所做的操作是可以并行操作的,结果互不影响。
这里主要的目的就是两个进程互斥地进入critical section。
那么为什么这个算法是可行的呢?
这样的算法可行,需要满足三个条件:
1 Mutual exclusion: 互斥进入
2 Progress : 在非remaider section的进程能在一定时间内进入critical section
3 Bounded waiting: 保证一个进程的等待时间不会过长
分析:
假设1 : 两个进程P1, P2同时执行了do语句:语句执行为:P1 flag[i] = true; P2 flag[j] = true; P1 turn = j; P2 turn = i; P1 while(flag[j] && turn == j) ;
这个时候由于P2已经执行了turn = i语句,所以turn == i,那么P1的语句while(flag[j] && turn == j)的turn ==j就为假了,所以这个时候退出循环,P1进入critical section。
然后P2 while (flag[i] && turn == i);因为这个时候flag[i] 和turn ==i都为真,那么P2就处于等待状态。因为P1和P2是等同的,所以这个情况下,只能有一个进程可以进入critical section的。条件1成立。
如果继续执行,那么就可以分析条件2也是成立的:因为P1进入了critical section之后执行完毕,退出来,那么flag[i] = false,这个语句执行之后,P2 while(flag[i] && turn == i)的flag[i]就为假了。之歌时候P2就可以进入critical section了。
那么继续分析条件3,可以知道P2的等待时间只是P1执行critical section的时间。这个等待时间一般不会过长。
其他情况就更加不会冲突了,可以列举所有语句执行的顺序知道,无论两个进程的语句如何执行,这个算法都是成立的。
--参考资料:Operating System Concepts
Operation System - Peterson's Solution算法 解决多线程冲突,布布扣,bubuko.com
Operation System - Peterson's Solution算法 解决多线程冲突