当前位置: 首页 > news >正文

2.3_2 进程互斥的软件实现方法

2.3_2 进程互斥的软件实现方法

进程互斥的软件实现方法
单标志法
双标志先检查
双标志后检查
Peterson算法

单标志法

这块儿代码是基于我看的B站视频改进的,我认为他的代码逻辑不很好理解,所以,可能不是很正确

int turn = 0;	//turn表示当前允许进入临界区的进程号
while(true){//P0进程					   	   while(turn==0){					critical section;				turn = 1;						remainder section;				}//P1进程while(turn==1){critical section;turn = 0;remainder section;}
}

注意:上面P0和P1部分的代码是并发执行的

turn的初始值为0,刚开始只允许P0进程进入临界区。

P0进程的时间片结束后,turn变为1,此时只有P1进程可以访问临界区。

该算法可以实现同一时刻最多只允许一个进程访问临界区

主要问题:违背"空闲让进"原则

只能按P0→P1→P0→P1→ …… 这样轮流访问。这种必须“轮流访问”带来的问题是,如果此时允许进入临界区的进程是P0,而P0一直不访问临界区,那么虽然此时临界区空闲,但是并不允许P1访问。

双标志法先检查

算法思想:

设置一个布尔型数组 flag[],数组中各个元素用来标记各进程是否处于临界区内,比如“flag[0]=ture”意味着0号进程P0现在正在临界区内。每个进程在进入临界区之前先检查当前有没有别的进程处于临界区内。如果没有,则把自身对应的标志flag[i]设为true,之后开始访问临界区。

bool flag[2];
flag[0]=false;
flag[1]=false;while(true){//P0进程while(flag[1]!=1){flag[0]=true;critical section;flag[0]=false;remainder section;}//P1进程while(flag[0]!=1){falg[1]=true;critical section;flag[1]=false;remainder section;}
}

注意:上面P0和P1部分的代码是并发执行的

主要问题:如果按照7行、15行、8行、16行这样的顺序来执行的话,临界区会被P0和P1同时访问。违反"忙则等待"原则

问题在于,进入区的"检查"和"上锁"两个处理不是一气呵成的,"检查"后"上锁"前有可能发生进程切换。

双标志后检查

算法思想:双标志先检查法的改版。前一个算法的问题是先“检查”后“上锁”,但是这两个操作又无法一气呵成,因此导致了两个进程同时进入临界区的问题。因此,人们又想到先“上锁”后“检查”的方法,来避免上述问题。

bool flag[2];
flag[0]=false;
flag[1]=false;while(true){//P0进程flag[0]=true;8while(flag[1]!=1){9critical section;flag[0]=false;remainder section;}//P1进程flag[1]=true;16while(flag[0]!=1){17critical section;flag[1]=false;remainder section;}
}

注意:上面P0和P1部分的代码是并发执行的

主要问题:如果按照8行、16行、9行、17行这样的顺序来执行,每个进程都发现对面上锁了,都无法访问。

因此,双标志后检查法虽然解决了“忙则等待”的问题,但是又违背了“空闲让进”和“有限等待”原则,会因各进程都长期无法访问临界资源而产生“饥饿”现象

Peterson算法

算法思想:结合双标志法、单标志法的思想。如果双方都争着想进入临界区,那可以让进程尝试“孔融让梨”(谦让)。做一个有礼貌的进程。

bool flag[2];
int turn = 0;	//表示优先让哪个进程进入临界区//P0进程
flag[0]=true;
turn=1;
while(flag[1] && turn==1);	//如果为真,则卡在这一步
critical section;
flag[0]=false;
remainder section;//P1进程
flag[1]=true;
turn=0;
while(flag[0] && turn==0);	//如果为真,则卡在这一步
critical section;
flag[1]=false;
remainder section;

Peterson算法用软件方法解决了进程互斥问题,遵循了空闲忙进、忙则等待、有限等待三个原则,但是依然未遵循让权等待的原则。

即:如果一个进程一直进不了临界区,那么会一直被卡在while循环。但是自己还在CPU上运行,不断检查while循环的条件是否得到满足。虽然这个进程进不了临界区,但是依然占用CPU资源


知识回顾与重要考点

相关文章:

  • java类和对象的思想概述
  • .net core webapi 大文件上传到wwwroot文件夹
  • 微服务之配置中心与服务跟踪
  • 【Grafana】Grafana匿名访问以及与LDAP连接
  • Git常用命令分享
  • 论文笔记 | ICLR 2023 WikiWhy:回答和解释因果问题
  • Sentinel 流量治理组件教程
  • 用C#也能做机器学习?
  • 在MongoDB中使用数组字段和子文档字段进行索引
  • SQL---Zeppeline前驱记录与后驱记录查询
  • 测试理论知识三:测试用例、测试策略
  • Spring AOP入门指南:轻松掌握面向切面编程的基础知识
  • 百度百科如何创建品牌词条?
  • CSRF检测工具(XSRF检测工具)使用说明
  • FFmpeg 简单文档
  • [PHP内核探索]PHP中的哈希表
  • [LeetCode] Wiggle Sort
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 【译】理解JavaScript:new 关键字
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • 78. Subsets
  • CSS盒模型深入
  • Docker: 容器互访的三种方式
  • JavaWeb(学习笔记二)
  • JAVA之继承和多态
  • JS基础之数据类型、对象、原型、原型链、继承
  • JS实现简单的MVC模式开发小游戏
  • Linux CTF 逆向入门
  • Nacos系列:Nacos的Java SDK使用
  • Vue2.x学习三:事件处理生命周期钩子
  • vuex 学习笔记 01
  • 当SetTimeout遇到了字符串
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 反思总结然后整装待发
  • 基于axios的vue插件,让http请求更简单
  • 蓝海存储开关机注意事项总结
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 为视图添加丝滑的水波纹
  • 延迟脚本的方式
  • 怎么将电脑中的声音录制成WAV格式
  • 阿里云ACE认证学习知识点梳理
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (2.2w字)前端单元测试之Jest详解篇
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (第61天)多租户架构(CDB/PDB)
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • (转)mysql使用Navicat 导出和导入数据库
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据