Peterson解法

线程同步-mutex方案-Peterson方案 关于线程同步的操作系统实验,自己写的实现了mutex方案和Peterson方案两种方法解决临界区问题。测试没问题。 立即下载

当你自行搜索到这篇文章的时候,想必已经对进程间通信有了一定的了解,如果不太了解也没关系,我会简单讲解下关于进程间通信的相关内容。

我们想要把信息从一个进程传递到另一个进程,无非是使用公共的存储区,有可能是在内存中,也有可能是一个共享文件,这就是进程间通信。但是有个问题,因为中断的原因,可能进程1读取到公共内存的的时候,切换到了进程2,进程2中对公共内存进行了修改,当进程2运行一段时间切换到进程1的时候,进程1的数据已经算是旧数据了,但进程1并不知道,仍然使用旧数据进行操作,当进程1操作完写回到公共内存时,数据就已经乱了。这里,我们把多个进程读写某些共享数据,而最后的结果取决于进程运行的精确时序,称为竞争条件(引用自《现代操作系统 第4版》)。

假设我们把对共享内存操作的程序片段称为临界区(引用自《现代操作系统 第4版》),我们接下来的目标,就是保证同一个时刻,只能有一个进程对临界区进行操作。

首先我们想想,为什么会产生竞争条件这样的问题?是不是因为中断机制的原因,使得CPU在执行一个进程片段一段时间后,就跑去执行另一个进程,那我们只用保证CPU在进入临界区后,屏蔽掉所有中断,这样,自然就只会执行当前进程,是不是就不会有竞争条件的问题?对的!但是,屏蔽中断有个致命的问题,他只能对当前CPU屏蔽,如果是多核情况下,屏蔽中断就并不管用了。

也许你会想,那我们是不是有个东西能同时屏蔽掉所有CPU的中断呢?对啦!那就是内存总线。啥是内存总线?简单来说,就是所有CPU都是通过这个内存总线,对内存进程访问的。我们只要锁住这个内存总线,就能保证只能有一个CPU对内存区访问,这个是硬件支持的一种方案,叫做TSL指令,这个会再写一篇文章进行详解,接下来我们将考虑怎么用软件的方式去解决竞争条件问题。

首先,我们考虑这样一个问题,是不是我们可以在某个进程A已经访问临界区,当另一个进程B也想访问的时候,用某种方式告诉进程B,公共内存有人在访问,你别访问了。这样貌似可行,那我们可以用一个布尔型变量来声明临界区是否可以访问。每个进程在访问临近区的时候,都先看看这个变量,看看能不能访问临界区,这样一来,就可以保证同一时刻只能执行一个进程了。

这个变量,我们可以称为锁变量。但是,有个问题,这个锁变量,本质上也是竞争条件问题,因为假设进程A在进入临界区前,判断这个变量后,能进入临界区,这个时候CPU切换到进程B,进程B一看,也能进入,这样一来,就又会出现竞争条件问题。

我们来仔细想想,为什么这个锁变量会有竞争条件问题,是不是因为,他可以被多个进程访问,那既然不考虑硬件支持,我们可不可以,使得这个变量,即时让多个进程同时读到,也没关系呢?

也就是说,目前这个锁变量,只有0和1,0代表当前进程能访问,1代表当前进程不能访问,进程A读到锁变量为0,切换到进程B也读到锁变量为0,结果他们同时访问了临界区。

那能不能我们把这个锁变量改成一种类似于hashmap的结构呢?key是当前进程ID,value是0或1,当进程A访问临界区的时候,先把value设置成1,代表A想要访问临界区,这个时候锁变量结构类似于这样:lock{A=1},紧接着再判断lock变量内,是否有其他的key,value = 1,如果没有,就直接进入临界区,如果有,该进程就循环判断直到没有为止。

我们来看看进程A和进程B同时想要进入临界区的情况是怎么样的:

  1. 进程A设置lock变量为1,此时lock变量为lock{A=1};
  2. 切换到进程B执行;
  3. 进程B设置lock变量为1,此时lock变量为lock{A=1,B=1};
  4. 进程B判断出有其他进程想要进入临界区,则循环判断lock变量;
  5. 切换到A进程执行;
  6. 进程A判断出有其他进程想要进入临界区,则循环判断lock变量;

。。。。。

好吧,进程A和进程B都在等别的进程出去临界区,但是谁都进不去,也出不来,结果死锁了,GG。

为啥会死锁呢?是不是因为进程A和进程B都在等另一个执行完?那如果,我们在这种情况下,选择一个进程,执行完,是不是另一个进程就能执行下去了呢?

Good!那我们这样改试试,上面这个变量称为感兴趣变量,因为代表哪个进程想进入临界区嘛,我们再加一个锁变量,用来标记哪个进程在执行,这个锁变量就存进程ID。

具体情况如下:

  1. 进程A设置感兴趣变量为1,此时感兴趣变量为{A=1},然后将lock变量设置为A;              ins :{A=1},  lock = A
  2. 切换到进程B执行;                                                                                                             ins :{A=1},  lock = A
  3. 进程B设置感兴趣变量为1,此时感兴趣变量为{A=1,B=1},然后将lock变量设置为B;    ins :{A=1,B=1},  lock = B
  4. 关键点来了,当lock变量为当前进程ID,并且其他变量为1的时候,当前进程就循环不进入临界区;(注意!是lock为当前进程ID,不进入临界区哦)      
  5. 假如B接着执行,因为ins内A = 1,并且lock  = B,所以B循环;                                        ins :{A=1,B=1},  lock = B
  6. 假如A接着执行,因为ins内B = 1,lock = B,所以A可以执行进入临界区;                       ins :{A=1,B=1},  lock = B
  7. A执行完,设置ins = 0;                                                                                                      ins :{A=0,B=1},  lock = B
  8. 切换到进程B执行;                                                                                                             ins :{A=0,B=1},  lock = B
  9. 因为A = 0,所以进入临界区;

再次提醒,lock变量其实代表哪个进程不能执行,当然你可以能会想,为什么不能判断条件当lock变量为当前进程ID,并且其他变量为0的时候,当前进程进入临界区呢

我们来看看这种情况会是怎么样:

  1. 进程A设置感兴趣变量为1,此时感兴趣变量为{A=1},然后将lock变量设置为A;             ins :{A=1},  lock = A
  2.        切换到进程B执行;                                                                                                             ins :{A=1},  lock = A
  3.        进程B设置感兴趣变量为1,此时感兴趣变量为{A=1,B=1},然后将lock变量设置为B;    ins :{A=1,B=1},  lock = B
  4.        假如B接着执行,因为ins内A = 1,并且lock  = B,所以B循环;                                        ins :{A=1,B=1},  lock = B
  5.        假如A接着执行,因为ins内B = 1,并且lock  = B,所以A循环; 

这种情况下,仍然会进入死锁的状态,所以是不可行的。

像上面这种,感兴趣变量加锁变量的方式,就是Peterson解法的思想。这种方法也同样适用于多线程。

保姆级教程:用SSC Tool 5.13为先楫HPM6E00EVK生成8轴EtherCAT从站代码(含XML配置详解) 本文详细介绍了如何使用SSC Tool 5.13为先楫HPM6E00EVK开发板配置8轴EtherCAT从站,包括XML文件深度配置、代码生成与工程整合、烧录与调试技巧。教程涵盖从环境准备到性能优化的全流程,帮助开发者快速实现符合CIA402标准的8轴控制。 阅读详情

相关推荐

MoveIt控制睿尔曼RM65机械臂:从仿真到实机的3种控制模式对比

本文详细解析了使用MoveIt框架控制睿尔曼RM65机械臂的三种核心模式:拖动规划、目标姿态规划和Python API控制,从Gazebo仿真到实机部署的完整实现路径。通过ROS环境配置、控制参数优化及实机过渡技术,为工业自动化和机器人研究提供实用指南。

727

帕特森(Peterson)解决方案

但是,在Peterson解决方案中,死锁永远不会发生,因为首先设置转向变量的进程肯定会进入临界区。同时,进程P1被抢占,进程P2被计划。在指令5中,由于它不满足条件(其他感兴趣的变量的值仍然为真),它被卡住了。现在,如果P2检查,那么它将满足条件,因为其他进程的感兴趣变量变为false。在入口部分,while条件涉及两个变量的标准,因此一个进程无法进入临界区,直到另一个进程感兴趣,并且进程是最后一个更新转向变量。但是,Peterson解决方案为您提供了所有必要的要求,例如互斥,进度,有限等待和可移植性。

unber的博客 776

Zynq7000双核裸机开发实战:如何安全实现共享内存与乒乓RAM设计

本文深入探讨了Zynq7000双核裸机开发中的共享内存与乒乓RAM设计,重点解析了核间通信的Cache一致性处理机制和硬件级实现方案。通过实战代码示例和性能优化技巧,帮助开发者解决双核运行中的访问冲突问题,提升嵌入式系统开发效率。

weixin_29191669的博客 376

Peterson解答

前言 有关Peterson解答的记录; 若有不当之处,请您指出,你的指点是我的荣幸! Peterson解答 Peterson解答是一个经典的基于软件的临界区问题的解决方案 Peterson算法适用于两个进程交错执行临界区与剩余区 在本文中,这两个进程分别是P0和P1 Peterson解答要求两个进程共享两个数据项 int turn; boolean flag[2]; 变量turn表示哪个进程可以进入临界区;即如果turn==i,那么进程Pi允许在临界区内执行。数组flag表示哪个进程准备进入临界区。 例

cb的博客 551

医疗器械软件测试输出内容(1)

*单元测试(Unit Testing):**单元测试是软件测试的最底层,用于验证软件中最小的可测试单元——函数、方法或模块。系统测试是在集成测试之后进行的,它对整个系统进行测试,验证系统在不同部分集成在一起后是否满足需求和规格。: 集成测试是在单元测试之后进行的,它关注不同单元之间的交互和集成。对于不同安全级别的软件(IEC 62304 A类、B类、C类),在体系上要求输出的文件内容有所区别。**说明:**将集成测试和软件系统测试合并为一项单一的计划和一组活动是可接收的。

ct745363083的博客 1867

信息化建设项目前期方案编制4:如何画好四张图

这里探讨以下具体的总体设计操作层面的工作。总体设计主要是完成四张图,总体架构(逻辑架构)、应用架构、网络拓扑、系统部署图。对于一些单一的系统,往往总体架构和应用架构可以合一。网络拓扑画好了,系统部署图也可以省略。有些项目还会在这之外,有所谓的技术架构图。对应用系统、数据存储等各个部分各自用的主要技术、服务等,给出总体设计图。但通常来说,这四张图在一个中等规模(200~500万,软件...

Leonardo的博客 4636

操作系统:同步

目录前言一、背景二、临界区问题三、Peterson解决方案四、硬件同步五、互斥锁六、信号量七、经典同步问题八、管程 前言 协作进程能与系统内的其他执行进程互相影响。协作进程或能共享逻辑地址空间,或能通过文件或消息来共享数据。 然而,共享数据的并发访问可能会导致数据的不一致。本章讨论多种机制,以便确保共享同一逻辑地址空间的协作进程能有序执行,从而维护数据的一致性。 一、背景 如果没有进程间的同步保障机制会发⽣什么样的问题? 发生竞争条件问题,即多个进程并发访问和操作同一数据并且执行结果与特定的访问顺序有关。

偶滴博客 1653

从一根USB线缆说起:深入浅出聊聊那些影响信号完整性和EMC性能的‘小细节’(双绞、屏蔽、360度搭接全解析)

本文深入探讨了USB线缆中影响信号完整性和EMC性能的关键细节,包括双绞线绞距、屏蔽层设计和360度搭接工艺。通过实验数据和实用技巧,揭示了这些‘小细节’如何显著影响高频信号质量和电磁兼容性,为工程师提供了从选购到系统设计的全面指南。

weixin_30824479的博客 439

03- 进程协作-Peterson 算法(Windows系统)

Peterson算法是实现进程互斥访问临界区的一种方法,避免了单标志法必须交替访问的限制,以及双标志法后检验的“饥饿”问题。//操作系统 临界区互斥Peterson's Algorithm算法思考Pi:turn = j;// 访问临界区// 剩余区Pj:turn = i;critical sectionl// 访问临界区// 剩余区。

March_A的博客 1561

LCL滤波器参数设计实战:从理论约束到工程选型指南

本文提供了LCL滤波器参数设计的实战指南,从理论约束到工程选型逐步拆解。核心在于平衡总电感量、电感比与电容值,确保谐振频率落在安全区间,以满足并网电流谐波标准并维持系统稳定。文章以10kW并网逆变器为例,给出了具体的参数计算流程与选型步骤,并强调了寄生参数、阻尼设计等工程实现细节。

c6d7e8f9g的博客 922

QT-使用ECharts显示地图,还有更多惊艳的图表等待你的使用

QT-使用ECharts显示地图前言一、使用步骤1.下载示例2. QT使用HTML文件配置3.使用HTML文件4. 数据交互及自适应总结注意:这个地图是百度的在线地图,需要百度API密钥和在联网的状态下使用。离线使用图表 前言 我上文QT图表chart-饼状图,使用qt自带的图表库charts来显示图表,实现数据可视化,但是QT自带的图表库显示效果并不佳,通俗说,就是不好看。 然而,有这么一个开源图表库,图表种类极多,并且效果良好,能够实现具有很好的视觉冲击的数据可视化。 它就是Apache ECharts

博咯的博客 4898

3.3 进程同步

一、信号量 1.1 引入信号量 ​ 下列是一段最简单的生产者与消费者的代码: ​ 二者通过 counter 来作为信号进行协作,但是这里存在一个问题,就是如果有两个生产者 P1 和 P2,当缓冲区满的时候,P1 和 P2 都被挂起,然后消费者消费了一个数据,P1 被唤醒,此时 counter 就小于 BUFFER_SIZE 了,所以 P2 可能永远不被唤醒。 ​ 导致上述问题的关键在于信号能够表示的信息太少了,它只表示了是否有进程正在被挂起,而没有表示当前挂起了几个进程,所以这里就引入了一个数据结构——信

stable_zl的博客 432

PADS导出PCB正反面丝印为CAD文件的方法

本文介绍如何将PADS绘制的pcb格式的PCB文件顶底层丝印及板框导出为CAD的dxf文件格式,并且将底层丝印进行镜像为正常视角

luguodeyo的博客 3295

操作系统——进程间通信Peterson解法代码简析

Peterson解法解决的是进程中竞争的问题,比如:有两个进程——进程0、进程1要读取共享内存中的数据,假设他们几乎同时进入了共享内存中,那么就会造成一定的问题。 代码如下: #define N 2 //进程数为2 int turn; //现在轮到哪个进程? int interested[N]; //初始化置为false,即没有在临界区等待读写共享数据的 void enter_

ACMartin的专栏 2397

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

[转]Operating System-进程间互斥的方案-保证同一时间只有一个进程进入临界区(2)- Peterson解法

  本文接上一篇文章继续介绍如何实现同一时间只允许一个进程进入临界区的机制。本文主要介绍Peterson解法。 方案汇总 屏蔽中断 锁变量 严格轮换法 TSL指令 Peterson解法 一、Peterson解法 基于锁变量以及严格轮换的方法1981年,有位叫Peterson的大师提供了一个更加简单的方法来解决进程间互斥。 代码 #define N 2 //进程数为2 in...

qq_29533283的博客 241

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Operating System-进程间互斥的方案-保证同一时间只有一个进程进入临界区(2)- Peterson解法...

本文接上一篇文章继续介绍如何实现同一时间只允许一个进程进入临界区的机制。本文主要介绍Peterson解法。 方案汇总 屏蔽中断 锁变量 严格轮换法 TSL指令 Peterson解法 一、Peterson解法 基于锁变量以及严格轮换的方法1981年,有位叫Peterson的大师提供了一个更加简单的方法来解决进程间互斥。 代码 #define N 2 //进程...

a9621196211的博客 543

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

互斥——Peterson解法(个人见解)

//原版的Peterson互斥算法 #define TRUE 1#define FALSE 0#define N 2                      /*进程的数量*/ int interested[N] = {0};               //所有值的初始化为0(FALSE) int turn;                     //现在轮到谁? vo...

weixin_30768175的博客 373

操作系统—读者-写者问题及Peterson算法实现

读者-写者问题及Peterson算法实现

Voltline的博客 2156

无锁编程(三) - 忙等待

忙等待可以看作一种特殊的无锁编程,本文详细介绍了忙等待的概念,忙等待的分类,并给出使用方法和范例

路漫漫其修远兮 2156

操作系统笔记-5-进程&线程同步

引言 前一篇介绍了进程和线程调度,知道线程和进程在系统中是并发执行,这将会引发出一些问题。接下来从一个简单的生产者和消费者例子说起,从前有两个进程,一个进程负责往一个buffer里写数据,我们把它叫做生产者;一个进程负责消费数据也就是取走buffer里的数据,我们把它叫做消费者。因为我们要记录写到哪里,所以需要一个变量in来记录,还需要一个变量记录消费到哪里了out,现在我们假设核心的生产者代码段。 while (true) { while (count == BUFFER SIZE)

houwanfeimark的专栏 620

《现代操作系统》精读与思考笔记 第二章 进程和线程

《现代操作系统》的阅读笔记第二篇。本节重点介绍:进程数&I/O频率&CPU利用率的关系、Peterson解法、实时系统任务可调度性的推导、哲学家进餐问题的一个高并行性解等。

Cyberspace 1888

操作系统学习笔记: 进程间通信

参考资料: 《现代操作系统 3th edtion》原书第二章 进程与线程 在 xmind 上记录 一、临界区 对共享内存进行访问的程序片段称作临界区域(critical region)或临界区(criticalsection) 使并发进程正常协作的条件 任何两个进程不能同时处于其临界区 不应对CPU的速度和数量做任何假设 临界区外运行的进程不得阻塞其他进程 不得使进程无限期等待进入临界区 ...

我的博客 261

西电计科操作系统复习要点:进程与线程

看往年题感觉很重视概念的考查, 所以这里首先给出这一章节的思维导图: 根据往年的卷子,这一章是考查的重点,相关的算法也经常出现,这里做了下面的整理: 进程间通信:共享资源的互斥访问方法 1、忙等待 1.1 自旋锁:A lock that uses busy waiting 对于自旋锁解决关键区问题的代码: /*自旋锁的解法*/ //进程0的程序: while(TRUE){ while(turn != 0); //注意循环被分号终止 criticial_region(); //关键区代码

weixin_45745854的博客 387

进程间通信:忙等待和信号量以及管程相关程序详解

进程间通信:共享资源的互斥访问方法 1、忙等待 1.1 自旋锁:A lock that uses busy waiting 对于自旋锁解决关键区问题的代码: /*自旋锁的解法*/ //进程0的程序: while(TRUE){ while(turn != 0); //注意循环被分号终止 criticial_region(); //关键区代码 turn = 1; //关键区结束,改变自旋锁的值,使进程1能够进入 noncriticial_region(); //非关键区代码 } /

weixin_45745854的博客 1789

从操作系统到二进制安全 第二章:线程与进程(中)

线程之所以通信方便,因为共享一个地址空间,而进程中的通讯,也可以通过共享地址空间或者共享一个文件,但是就会出现一些问题。

2301_80140310的博客 1035
上一篇: 操作系统——内存(思维导图)
下一篇: Java 文件NIO 中,为什么NIO比IO快?
鱼阿鱼
博客等级 码龄11年 23粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值