操作系统进程互斥的四种软件实现和三种硬件实现
进程互斥是操作系统中保证多个进程不会同时访问共享资源的一种机制。
进程互斥的四种软件实现方式:
一、单标志法
-
核心思想:使用一个布尔变量(或称为标志位)来表示临界区的访问权限。该变量为true时表示允许某个进程访问临界区,为false时表示不允许。
-
实现方式:
- 初始化时,标志位设为false,表示没有进程可以访问临界区。
- 进程在进入临界区之前,会检查这个标志位。如果标志位为false,则进程会等待(通常是通过循环检查);如果标志位为true,则进程可以进入临界区,并将标志位设为false,表示其他进程不能进入。
- 进程退出临界区时,将标志位重新设为true,表示允许其他进程进入。
// 假设有一个全局布尔变量 flag,初始化为 false
boolean flag = false;// 进程 A 的代码
while (true) {while (flag); // 忙等待,直到 flag 为 falseflag = true; // 进入临界区// 临界区代码flag = false; // 退出临界区// 非临界区代码
}// 进程 B 的代码与进程 A 类似,只是变量名和逻辑上是独立的(但在这个例子中共享了 flag)
-
优缺点:
- 优点:实现简单。
- 缺点:不遵循“空闲让进”原则,即如果当前进程不访问临界区,即使临界区空闲,其他进程也无法访问。
二、双标志先检查法
-
核心思想:使用两个布尔变量(或称为标志数组)分别表示两个进程是否想要进入临界区。
-
实现方式:
- 每个进程在进入临界区之前,先检查另一个进程的标志位。如果另一个进程的标志位为false(表示不想进入临界区),则将自己的标志位设为true,并尝试进入临界区。
- 如果另一个进程的标志位为true,则当前进程会等待。
// 假设有两个全局布尔变量 flagA 和 flagB,分别表示进程 A 和进程 B 是否想要进入临界区
boolean flagA = false, flagB = false;// 进程 A 的代码
while (true) {flagA = true; // 表示想要进入临界区while (flagB); // 如果进程 B 也想进入临界区,则等待// 临界区代码flagA = false; // 退出临界区// 非临界区代码
}// 进程 B 的代码与进程 A 类似,只是使用 flagB 而不是 flagA
注意:双标志先检查法存在竞态条件,即两个进程可能同时修改标志位并同时进入临界区。
-
优缺点:
- 优点:相比单标志法,双标志先检查法在一定程度上提高了灵活性。
- 缺点:违反了“忙则等待”原则,因为在“检查”和“上锁”之间可能发生进程切换,导致两个进程同时进入临界区。
三、双标志后检查法
-
核心思想:也是对双标志先检查法的改进,采用先“上锁”后“检查”的方法来避免两个进程同时进入临界区的问题。
-
实现方式:
- 进程在进入临界区之前,先将自己的标志位设为true,表示想要进入临界区。
- 然后检查另一个进程的标志位。如果另一个进程的标志位也为true,则当前进程会放弃进入临界区,并将自己的标志位重新设为false。
- 如果另一个进程的标志位为false,则当前进程可以进入临界区。
// 假设有两个全局布尔变量 wantA 和 wantB,以及一个整型变量 turn,初始化为 0(表示先让进程 A)
boolean wantA = false, wantB = false;
int turn = 0; // 0 表示进程 A 的回合,1 表示进程 B 的回合// 进程 A 的代码
while (true) {wantA = true; // 表示想要进入临界区turn = 1; // 设置 turn 为 B 的回合(但这一步是“后检查”的一部分)while (wantB && turn == 1); // 如果进程 B 也想进入且是 B 的回合,则等待// 临界区代码wantA = false; // 退出临界区// 非临界区代码
}// 进程 B 的代码与进程 A 类似,只是使用 wantB 和将 turn 设置为 0
注意:双标志后检查法解决了双标志先检查法中的竞态条件问题。
-
优缺点:
- 优点:解决了双标志先检查法中两个进程可能同时进入临界区的问题。
- 缺点:违背了“空闲让进”和“有限等待”原则,可能导致某些进程长期无法访问临界资源,产生“饥饿”现象。
四、Peterson算法
-
核心思想:通过引入一个额外的变量(通常称为turn)和一个“让权”机制来解决进程互斥问题。
-
实现方式:
- 初始化时,turn变量设为某个进程的编号(假设为0)。
- 进程在进入临界区之前,会检查turn变量是否等于自己的编号。如果不等,则进程会等待(通常是通过循环检查)。
- 如果turn变量等于自己的编号,进程还需要检查另一个进程的标志位是否为false。如果为true,则进程也会等待。
- 只有当turn变量等于自己的编号且另一个进程的标志位为false时,进程才能进入临界区。
- 进程退出临界区时,会将自己的标志位设为false,并将turn变量设为另一个进程的编号,表示允许另一个进程进入临界区。
-
优缺点:
- 优点:Peterson算法遵循了“空闲让进”、“忙则等待”和“有限等待”三个原则。
- 缺点:未遵循“让权等待”原则,即进程在等待进入临界区时会持续占用CPU进行忙等。
// 假设有一个全局信号量 mutex,初始化为 1
Semaphore mutex = 1;// 进程 A 的代码
while (true) {P(mutex); // 请求进入临界区(P 操作是“等待”信号量的意思)// 临界区代码V(mutex); // 退出临界区(V 操作是“释放”信号量的意思)// 非临界区代码
}// 进程 B 的代码与进程 A 类似,只是逻辑上是独立的(但在这个例子中共享了 mutex)
注意:信号量是实现进程同步和互斥的一种有效机制,但这里的伪代码只是为了说明概念。在实际应用中,你需要使用操作系统提供的信号量 API(如 POSIX 信号量)来实现。
在实际编程中,你通常会使用操作系统提供的同步原语(如互斥锁、信号量等)来实现进程互斥,而不是直接编写这些低级的算法。这些同步原语通常已经过优化和测试,能够提供更好的性能和可靠性。
进程互斥的硬件实现方式:
中断屏蔽方法、TestAndSet(TS)指令和Swap指令。
一、中断屏蔽方法
-
核心思想:利用“开/关中断指令”实现进程互斥。即在某进程开始访问临界区到结束访问为止都不允许被中断,也就不能发生进程切换,因此也不可能发生两个进程同时访问临界区的情况。
-
实现方式:在进程访问临界区之前,先执行一个关中断指令,阻止当前进程被中断。直到当前进程访问完临界区后,再执行开中断指令,允许其他进程被调度和执行。
-
优缺点:
- 优点:简单、高效。由于中断被屏蔽,因此不会出现进程切换,从而保证了进程互斥。
- 缺点:只适用于单处理机系统,并且只适用于操作系统内核进程,不适用于用户进程。因为开/关中断指令只能运行在内核态,如果用户进程能够随意使用这组指令,将会对系统的稳定性和安全性造成威胁。
二、TestAndSet(TS)指令
-
核心思想:TestAndSet指令是一种硬件支持的原子操作,用于检测并设置某个变量的值。在进程互斥的实现中,该指令可以用于检测临界区是否被锁定,并尝试设置锁定标志。
-
实现方式:
- 初始化时,设置一个布尔变量(如lock)为false,表示临界区未被锁定。
- 进程在进入临界区之前,执行TestAndSet指令。该指令会原子地检查lock的值,如果为false,则将其设置为true,并返回false;如果为true,则返回true。
- 如果TestAndSet指令返回false,表示临界区未被锁定,进程可以进入临界区。如果返回true,则表示临界区已被其他进程锁定,当前进程需要等待。
-
优缺点:
- 优点:实现简单,适用于多处理机环境。由于TestAndSet指令是硬件实现的原子操作,因此不需要担心逻辑漏洞。
- 缺点:不满足“让权等待”原则。当临界区被锁定时,等待的进程会占用CPU并循环执行TestAndSet指令,导致“忙等”。这可能会浪费CPU资源,并降低系统的吞吐量。
三、Swap指令
-
核心思想:Swap指令(也称为Exchange指令或XCHG指令)是另一种硬件支持的原子操作,用于交换两个变量的值。在进程互斥的实现中,Swap指令可以用于交换临界区的锁定标志和当前进程的标志。
-
实现方式:
- 初始化时,设置一个布尔变量(如lock)为false,表示临界区未被锁定。同时,为每个进程设置一个标志变量(如old),用于记录临界区的锁定状态。
- 进程在进入临界区之前,执行Swap指令。该指令会原子地交换lock和old的值。
- 如果Swap指令执行后,old的值为false,表示之前没有其他进程对临界区上锁,因此当前进程可以进入临界区。如果old的值为true,则表示临界区已被其他进程锁定,当前进程需要等待。
-
优缺点:
- 优点:实现简单,适用于多处理机环境。与TestAndSet指令类似,Swap指令也是硬件实现的原子操作,因此不需要担心逻辑漏洞。
- 缺点:同样不满足“让权等待”原则。当临界区被锁定时,等待的进程会占用CPU并循环执行Swap指令,导致“忙等”。
相关文章:
操作系统进程互斥的四种软件实现和三种硬件实现
进程互斥是操作系统中保证多个进程不会同时访问共享资源的一种机制。 进程互斥的四种软件实现方式: 一、单标志法 核心思想:使用一个布尔变量(或称为标志位)来表示临界区的访问权限。该变量为true时表示允许某个进程访问临界区&…...
C++虚继承演示
在继承中如果出现: 这种情况,B和C都继承了A,D继承了B、C 在D中访问A的成员会出现: 这样的警告 是因为在继承时A出现两条分支:ABD、ACD 编译器不知道访问的A中的元素是经过B继承还是C继承 所以B、C在继承A时要用到…...
React Native的生命周期
React Native 组件的生命周期分为三个阶段:Mounting(挂载)、Updating(更新) 和 Unmounting(卸载)。每个阶段都会触发不同的生命周期方法。 下面是详细的生命周期解释,并通过一个项目…...
linux系统中涉及到用户管理的命令知识
用户创建与密码设置 Linux中新建用户使用useradd命令,只有root用户才能执行,若useradd命令直接输入不管用,可使用绝对路径/usr/sbin/useradd。设置用户登录密码使用passwd命令。 su命令相关 su代表switch user,用于切换用户。切换…...
LeetCode 0685.冗余连接 II:并查集(和I有何不同分析)——详细题解(附图)
【LetMeFly】685.冗余连接 II:并查集(和I有何不同分析)——详细题解(附图) 力扣题目链接:https://leetcode.cn/problems/redundant-connection-ii/ 在本问题中,有根树指满足以下条件的 有向 图。该树只有一个根节点&…...
Dubbo负载均衡
负载均衡策略与配置细节 Dubbo 内置了 client-based 负载均衡机制,如下是当前支持的负载均衡算法,结合上文提到的自动服务发现机制,消费端会自动使用 Weighted Random LoadBalance 加权随机负载均衡策略 选址调用。 如果要调整负载均衡算法…...
PymuPDF4llm提取pdf文件文字、表格与图片
一、PymuPDF4llm 的功能特点 (一)文本提取 简单易用 PymuPDF4llm 的文本提取功能非常简单易用。只需使用pip install pymupdf4llm进行安装,然后通过import pymupdf4llm导入库,就可以使用md_text pymupdf4llm.to_markdown("…...
20241108通过iperf3确认中科创达的高通CM6125的WIFI的网速【失败】
20241108通过iperf3确认中科创达的高通CM6125的WIFI的网速【失败】 2024/11/8 15:43 由于以太网不能用,那就测试一下WIFI,iperf3链接/测试异常。 一般认为可能的原因有: 1、CM6125开发板的WIFI不带天线,影响性能。 2、CM6125的And…...
Stored procedures in PostgreSQL
select 存储过程,在现了解的情况,还是没有mysql,sqlserver等好写好用。 --postgreSQL 11.0 以下版本 create or replace FUNCTION procInsertSchool (pSchoolId Char(5),pSchoolName VarChar(100),pSchoolTelNo VarChar(8) ) RETURNS void language plp…...
第10章 多表查询
一、什么是多表查询 多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。 前提条件:这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段,这个关联字段可能建立…...
【基于LSM的ELF文件安全模块设计】参考
《基于LSM的ELF文件安全模块设计文档》 一、设计目标 本设计致力于通过 Linux 安全模块(LSM)构建一个强大而严密的安全防护体系,以实现对 ELF 文件(涵盖可执行文件和动态链接库)的绝对严格的合法性和完整性检查。其核…...
全卷积和全连接
全连接网络和全卷积网络不一样 以下是对两者的正确解释和代码示例: 1. 全连接网络(Fully Connected Network) 全连接网络使用的是 线性层(nn.Linear),也就是我们常说的“全连接层”。它是用于将每一个输入…...
Unity图形学之Shader结构
Unity - Manual: ShaderLab: Legacy Lighting 1.Shader 语言: OpenGL:SGL 跨平台性能非常好 GLSL语言 OpenGL Shader LanguageDX:微软 非跨平台 性能非常好 HLSL语言 High Level Shader LanguageCG:微软和英伟达 联合开发CG …...
离散时间信号的产生
文章目录 前言1.单位冲激序列函数1.2 函数:1.3 实现代码:1.3 调用方式1.4 调用结果 2.单位阶跃序列函数2.1 函数2.2实现代码2.3调用方式2.4调用结果 3.矩形序列3.1函数3.2 实现代码3.3调用方式3.4 调用结果 4.实指数序列4.1函数4.2实现代码4.3调用方式4.…...
物联优化汽车齿轮锻造
在汽车齿轮的锻造工艺中,锻造温度、锻造压力与行程、锻造速度与锤击方式以及热处理工艺等核心参数扮演着举足轻重的角色。这些参数的精准控制与实时监测,对于提升生产效率、确保产品质量、削减生产成本以及推动生产智能化转型具有不可估量的价值。明达技…...
CocosCreator 构建透明背景应用(最新版!!!)
文章目录 透明原理补充设置截图以及代码step1: electron-js mian.jsstep2:ENABLE_TRANSPARENT_CANVASstep3:SOLID_COLOR Transparentstep:4 Build Web phonestep5:package electron-js & change body background-color 效果图补充 透明原理 使用Cocos creator 做桌面应用开…...
使用CentOS宝塔面板docker搭建EasyTier内网穿透服务
0. 前言 EasyTier是一个简单、安全、去中心化的内网穿透 VPN 组网方案,部署方便,支持 MacOS/Linux/Windows/FreeBSD/Android平台,而且作者搭建了一个公共服务器,不想折腾自建服务,可以使用默认的公共服务器地址 tcp:/…...
HTMLCSS: 实现可爱的冰墩墩
效果演示 HTML <div class"wrap"><div class"body"></div><div class"ear"></div><div class"ear rightEar"></div><div class"leftHand"></div><div class"…...
天地图入门|标注|移动飞行|缩放,商用地图替换
“天地图”是国家测绘地理信息局建设的地理信息综合服务网站。集成了来自国家、省、市(县)各级测绘地理信息部门,以及相关政府部门、企事业单位 、社会团体、公众的地理信息公共服务资源,如果做的项目是政府部门、企事业单位尽量选…...
Flutter PC端UI组件库
一、参考Element-ui的设计和交互,构建基于dart的Flutter UI组件库 https://javonhuang.github.io/sky-ui-page/index.html...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
