如何更好理解Peterson算法?

1 Peterson算法提出的背景

在我们讲述Peterson算法之间,我们先了解一下Peterson算法提出前的背景(即:在这个算法提出之前,前人们都做了哪些工作)这对于我们之后理解Peterson算法有很大的裨益。

Peterson 算法是基于双线程互斥访问的LockOne与LockTwo算法而来。LockOne算法使用一个 flag 布尔数组,LockTwo 使用一个 turn的整型量,都实现了互斥,但是都存在死锁的可能。Peterson 算法把这两种算法结合起来,完美地用软件实现了双线程互斥问题。

2 Peterson算法

首先,我们来看看下面这两段代码:

Pi进程:
flag[i] = True;
while(flag[j]);
critical section;
flag[i] = False;
remainder section;
Pj进程:
flag[j] = True;
while(flag[i]);
critical section;
flag[j] = False;
remainder section;

以上是用来实现两个进程互斥访问临界区的两端代码,我们可以这样来理解这两段代码,其中flag[i]表示进程Pi表示想要进入临界区,while(flag[j])可以理解为Pi在自己进临界区之前,先问问Pj是否想要进入临界区,如果Pj想进的话它就等待(Pi品德高尚);类似的,Pj也是同样的。双方互相谦让的结果是,最终两个进程谁也进不了临界区。(可以想象这样一个生活场景,两个人同时想进屋,结果在门口谦让了了半天,过了很久都没进去)

Peterson算法就是在上面代码的基础之上,又引入了一个变量turn,打破了这种因为谦让而导致“饥饿”的现象。下面我们先来看看Peterson算法的代码:

Pi进程:
flag[i] = True;
turn = j;
while(flag[j] && turn == j);
critical section;
flag[i] = False;
remainder section;
Pj进程:
flag[j] = True;
turn = i;
while(flag[i] && turn == i);
critical section;
flag[j] = False;
remainder section;

怎么理解变量turn呢?可以将turn变量理解成轮到谁进入临界区了。举个例子:turn = i,表示轮到Pi进入临界区。那么上面这个代码就可以理解为:首先,Pi想进入临界区(flag[i] = True),然后,还是和前面的代码一样,Pi会先把进入临界区的机会让给Pj(turn = j),同样地,当Pj想进入临界区时,也会将进入临界区的权利先让给Pi。紧接着,变量turn的作用就显现出来了,当Pj把进入临界区的机会又让给Pi的时候(注意:这是发生在Pi将进入临界区的优先权让给Pj之后),Pi这次就会直接进入临界区。就不会再次出现一直互相谦让,最终导致均无法进入临界区的情况了。

关于为什么当进入临界区的权利(即turn = i)又回到Pi手里时,Pi会直接进入临界区的分析?我们可以分析一下Pi能够成功进入临界区的条件(即:while(flag[j] && turn == j)语句):

总的分为以下两种情况:

  1. Pj不想进入临界区(flag[j] = False)

    当Pj不想进入临界区时,自然也就不存在Pi和Pj冲突的情况,Pi当然就直接进入临界区。

  2. Pj想进入临界区(flag[j] = True)

    当Pj想进入临界区,又分为以下两种情况:

  • 当 turn = i

    turn = i说明当前轮到i进入临界区了 ,这个时候i就直接进入临界区了,不再谦让。(其实这个挺合理的,根据Peterson算法的代码我们不难发现因为turn的值是根据先后想要进入临界区的顺序排列的)

  • 当 turn != i

    turn != i 说明当前轮到i进入临界区了没有轮到Pi进入临界区,Pi自然需要等待。

仅过上面的分析,我们就不难理解,当Pi和Pj经过一轮谦让之后,就会直接根据turn的值(即:该轮到谁进临界区了)来直接决定谁该进入临界区。现在回过头回顾整个算法,其实我们会发现,Peterson算法的思想会更贴近于生活中的真实情况,大家一般都是略微谦让一下,然后直奔主题,难道不是吗?哈哈

3 参考资料

[1]维基百科编者. Peterson算法[G/OL]. 维基百科, 2021(20210501)[2021-05-01]. https://zh.wikipedia.org/w/index.php?title=Peterson%E7%AE%97%E6%B3%95&oldid=65429794.

如何更好理解Peterson算法?的更多相关文章

  1. (转)进程同步之临界区域问题及Peterson算法

    转自:http://blog.csdn.net/speedme/article/details/17595821 1. 背景 首先,看个例子,进程P1,P2共用一个变量COUNT,初始值为0     ...

  2. Raft 为什么是更易理解的分布式一致性算法

    一致性问题可以算是分布式领域的一个圣殿级问题了,关于它的研究可以回溯到几十年前. 拜占庭将军问题 Leslie Lamport 在三十多年前发表的论文<拜占庭将军问题>(参考[1]). 拜 ...

  3. 【转】Raft 为什么是更易理解的分布式一致性算法

    编者按:这是看过的Raft算法博客中比较通俗的一篇了,讲解问题的角度比较新奇,图文并茂,值得一看.原文链接:Raft 为什么是更易理解的分布式一致性算法 一致性问题可以算是分布式领域的一个圣殿级问题了 ...

  4. Raft 为什么是更易理解的分布式一致性算法(转)

    一致性问题可以算是分布式领域的一个圣殿级问题了,关于它的研究可以回溯到几十年前. 拜占庭将军问题 Leslie Lamport 在三十多年前发表的论文<拜占庭将军问题>(参考[1]). 拜 ...

  5. 【转载】Raft 为什么是更易理解的分布式一致性算法

    一致性问题可以算是分布式领域的一个圣殿级问题了,关于它的研究可以回溯到几十年前. 拜占庭将军问题 Leslie Lamport 在三十多年前发表的论文<拜占庭将军问题>(参考[1]). 拜 ...

  6. Peterson算法与Dekker算法解析

    进来Bear正在学习巩固并行的基础知识,所以写下这篇基础的有关并行算法的文章. 在讲述两个算法之前,需要明确一些概念性的问题, Race Condition(竞争条件),Situations  lik ...

  7. 简单的理解deflate算法

    简单的理解deflate算法 最近做压缩算法. 用到了deflate压缩算法,  找了很多资料,  这篇文章算是讲的比较易懂的, 这篇文章不长,但却浅显易懂, 基本上涵盖了我想要知道的所有要点. 翻译 ...

  8. 理解 KMP 算法

    KMP(The Knuth-Morris-Pratt Algorithm)算法用于字符串匹配,从字符串中找出给定的子字符串.但它并不是很好理解和掌握.而理解它概念中的部分匹配表,是理解 KMP 算法的 ...

  9. 内存栅栏(memory barrier):解救peterson算法的应用陷阱

    最近一个项目中用到了peterson算法来做临界区的保护,简简单单的十几行代码,就能实现两个线程对临界区的无锁访问,确实很精炼.但是在这不是来分析peterson算法的,在实际应用中发现peterso ...

随机推荐

  1. 用程序员的思维了解Filecoin

    程序员接触一个新技术惯用步骤: 先搜索引擎搜索一波,找个最简单的解释.如果有了个大概的概念,就前往2.否则循环1->1->1...直到有个大概的概念为止. 上官网跑一遍. 各种论坛社区溜达 ...

  2. Android Studio 之 用 Drawable resource file 美化 Button 样式

    shape •新建 Drawable resource file 点击 app/src/main/res 找到 drawable 文件夹,右击->New->Drawable Resourc ...

  3. Android学习之探究Fragment

    •碎片是什么 Fragment是一种可以嵌入在活动中的UI片段,能够让程序更加合理和充分地利用大屏幕的空间: 出现的初衷是为了适应大屏幕的平板电脑,可以将其看成一个小型Activity,又称作Acti ...

  4. 极速精简 Go 版 Logstash

    前言 今天来介绍 go-zero 生态的另一个组件 go-stash.这是一个 logstash 的 Go 语言替代版,我们用 go-stash 相比原先的 logstash 节省了2/3的服务器资源 ...

  5. [状压DP]车II

    车 I I 车II 车II 题目描述 有一个 n ∗ m n*m n∗m的棋盘 ( n . m ≤ 80 , n ∗ m ≤ 80 ) (n.m≤80,n*m≤80) (n.m≤80,n∗m≤80)要 ...

  6. [Vue warn]: Unknown custom element: <terminal-process> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

    Vue组件注册报错问题 import 不要加{},排查出如果页面引用单个组件的时候不要加上{}中括号,引入多个组件时才能派上用场,中括号去除问题即可解决.

  7. Spring Cloud & Alibaba 实战 | 第十二篇: 微服务整合Sentinel的流控、熔断降级,赋能拥有降级功能的Feign新技能熔断,实现熔断降级双剑合璧(JMeter模拟测试)

    目录 一. Sentinel概念 1. 什么是Sentinel? 2. Sentinel功能特性 3. Sentinel VS Hystrix 二. Docker部署Sentinel Dashboar ...

  8. 1438. Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit

    Given an array of integers nums and an integer limit, return the size of the longest continuous suba ...

  9. 06- Linux Ubuntu下sublime下载与使用与安装包

    我有Linux下全套的安装包,如sublime,pycharm等.不用再苦逼的下软件了.需要的加我微信:chimu sublime text 3文本编辑器 启动命令:Linux命令行输入subl 或者 ...

  10. Pyqt5 combobox

    起因 combobox的使用和介绍 两个combobox 联动 开始 介绍 Combobox是Qt中的下拉复选框, 注意:在添加列表选项时,可以一个个添加,也可以直接使用列表一次性添加多个: 添加多个 ...