操作系统之进程同异步、互斥
引入
异步性是指,各并发执行的进程以各自独立的、不可预知的速度向前推进。
但是在一定的条件之下,需要进程按照一定的顺序去执行相关进程:
举例说明1:

举例说明2:

读进程和写进程并发地运行,由于并发必然导致异步性,因此“写数据”和“读数据”两个操作执行的先后顺序是不确定的。而实际应用中,又必须按照“写数据>读数据”的顺序来执行的。所以需要解决这种异步的问题,就是进程同步所讨论的内容。
进程互斥软件实现方法
一、临界区
1、临界资源

2、临界区的控制结构

3、临界区遵循的四个原则

二、进程互斥
1、为什么要进程互斥?
假设进程A在执行程序的时候需要调度打印机的资源,但是调度到一半的时候,操作系统给A分配的时间片用完了,这个时候进程B上处理机,也需要使用打印机,这个时候如果进程不互斥的话,就会将A、B的内容混在一起;因此需要进程互斥;
2、单标记法
两个进程在访问临界区的时候,使用临界区的权限由使用完临界区的进程转交给下一个需要使用临界区的进程;


缺点:只能轮流访问,当进程A访问打印机临界区的时候,时间片使用完毕之后,退出处理机,这时候进程B进入处理机,同时进程B也需要访问打印机,但是这个时候打印机的标记只能给进程A使用,所以进程B只能干等待,等待A下一次进入并且使用完临界区的时候,自己才能进入临界区处理资源, 显然不符合临界区的空闲让进原则;
3、双标志前检查法

使用数组记录想进入临界区的意愿,当进程A进入临界区的时候,需要将自己的意愿数组赋值为TRUE,其他进程进入时候,会判断A进程是否已经进入临界区,如果已经进入则自旋等待,等待A进程执行完毕后,将自己的意愿变为false,这时候其他进程可以进入;
缺点:使用数组表示想进入临界区意愿,若按照 ①⑤②⑥③⑦…的顺序执行,PO 和 P1将会同时访问临界区。因此,双标志先检查法的主要问题是:违反“忙则等待”原则。原因在于,进入区的“检查”和“上锁”两个处理不是一气呵成的。“检查”后, “上锁”前可能发生进程切换。
4、双标志后检查法
通过先上锁,后进入的方式

缺点:如果并发执行的话,同时上锁会导致都进不了临界区,违反了空闲让进和有限等待的原则,使得进程长期无法访问资源而产生饥饿现象;
5、Peterson算法
结合双标志方法,如果双方都争着想进入临界区,那可以谦让。

虽然Peterson算法解决了进程互斥,遵循空闲让进,忙则等待,有限等待三个原则,但是未遵循让权等待。
进程互斥硬件实现方法
一、中断屏蔽方法
类似原语,用“开/关中断指令” 实现(与原语的实现思想相同,即在某进程开始访问临界区到结束访问为止都不允许被中断,也就不能发生进程切换,因此也不可能发生两个同时访问临界区的情况)

优点:简单、高效
缺点:不适用于多处理机;只适用于操作系统内核进程,不适用于用户进程(因为开/关中忻指令只能运行在内核态,这组指令如果能让用户随意使用会很危险)
二、TestAndSet指令
简称TS 指令,也有地方称为 TestAndsetlock 指令,或TSL 指令,TSL指令是用硬件实现的,执行的过程不允许被中断,只能一气呵成。相当于存在一个全局变量,利用全局变量的值来控制访问临界区,以下是用C语言描述的逻辑

若刚开始lock 是false,则TSL返回的old 值为false,while 循环条件不满足,直接跳过循环,进入临界区。若刚开始lock是true,则执行TLS后old 返回的值为 true, while 循环条件满足,会一直循环,直到当前访问临界区的进程在退出区进行 “解锁”相比软件实现方法,TSL指令把 “上锁”和“检查” 操作用硬件的方式变成了一气呵成的原子操作。
优点:实现简单,无需像软件实现方法那样严格检查是否会有逻辑漏洞;适用于多处理机环境
缺点:不满足让权等待原则,不满足条件的时候会一直等待;
三、Swap指令

使用的方式TestAndSet一致,只是硬件层面实现不同,都是通过一个全局变量来控制是否能进入临界区;
四、互斥锁

特性:
•需忙等,进程时间片用完才下处理机,违反“让权等待”
•优点:等待期问不用切换进程上下文,多处理器系统中,若上锁的时间短,则等待代价很低
•常用于多处理器系统,一个核忙等,其他核照常工作,并快速释放临界区
•不太适用于单处理机系统,忙等的过程中不可能解锁
注:如果是多核的时候,一个进程自旋等待只会吃掉一个核,其他核访问完临界区之后,就会释放临界区,等待的进程也能进入临界区操作资源,但是在单核的时候,自旋的进程需要等待自己的时间片用完,并且等待使用临界区的进程上CPU释放临界区的资源才能继续使用临界区;
信号量机制
一、概述
1、由迪杰斯特拉提出信号量机制;
2、信号量是一种变量,表示系统中的一种变量;
3、使用一对原语来对信号量进行操作,wait(s)原语和signal(s)原语,可以把原语比做一个函数,括号里面的s其实就是函数调用的时候传入的一个参数;一般把原语简称为 P,V操作;
二、整型信号量
用一个整数表示系统资源的变量,用来表示系统中某种资源的数量
int S=1;
void wait(int S){ //wait原语,相当于:进入区while(S<=0); //如果资源数不够,就意志循环等待S=S-1; //如果资源数够,则占用一个资源
}void signal(int S){//signal原语,相当于“退出区”S=S+1; //使用完资源后,在退出区释放资源
}
相当于通过一个整形变量上锁,但是如果一个进程占用了临界区的资源,另一个进程需要访问临界区的资源的时候,会等待上一个进程使用完资源,这个时候会一直忙等待;
三、记录型信号量
1、记录型的信号量增加了等待队列,当进程发现临界区的资源已经被别的进程占用的时候,将自己设置为阻塞状态,并且放入新增的等待队列中,等待临界区的释放被唤醒;
//记录型信号量的定义
typedef struct{int value;struct process *L;
} semaphore;
//某进程需要使用资源时,通过wait原语申请
void wait (semaphore S){S.value--;if(S.value<0){block (S.L);//将该进程加入到消息队列中}
}
//进程使用完资源后,通过signal原语释放
void signal (semaphore S){S.value++;if(S.valie<=0){wakeup(S.L);}
}

五、使用信号量机制实现互斥
1、实现进程互斥
设置互斥信号量mutex,初值为1,对不同的临界资源需要设置不同的互斥信号量,PV必须成对出现
2、实现进程同步
保证一前一后的操作顺序,设置同步信号量S,初始为0,在“前操作”之后执行V(S,在“后操作”之后执行(V)
3、实现进程的前驱关系
(1)要为每一对前驱关系各设置一个同步变量
(2)在“前操作”之后对相应的同步变量执行V操作
(3)在“后操作”之前对相应的同步变量执行P操作
前V后P:信号量代表了某种资源,P2执行的时候需要P1来释放这种资源,这样就限制了P1一定在P2的后面执行;

进程同步问题
一、生产者消费者问题
只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待,只有缓冲区不空时,消费者才能从中取出产品,否则必须等待,缓冲区是临界资源,各个进程互斥访问,实现互斥的P操作要放在实现同步的P操作之后,不然会发生死锁,V操作不会导致进程发生阻塞的状态,所以可以交换,使用操作不要放在临界区,不然并发度会降低·

重点:生产消费问题为两个互斥同步的综合问题,需要两个信号量来控制;并且实现互斥的P操作一定需要在实现同步的P操作之后;
二、多生产者多消费者问题


三、吸烟者问题
解决“可以让生产多个产品的单生产者”问题提供一个思路;若一个生产者要生产多种产品(或者说会引发多种前驱事件),那么各个V操作应该放在各自对应的“事件”发生之后的位置

四、读者、写者问题
1、允许多个读者同时对文件执行读操作
2、只允许一个写者往文件中写信息
3、任一写者在完成写操作之前不允许其他读者或写者工作
4、写者执行写操作前,应让已有的读者和写者全部退出
1、直接全部加锁,但是不能读进程同步

2、加上count变量,第一个加锁即可


所以需要让对count的操作是互斥的

但是如果一直读进程进入的时候,写进程一直无法执行,导致饿死;所以在新增一个信号量w;用于实现写优先;当有写操作进入的时候,前面的读进程结束后就应该触发写进程了



最终代码逻辑:
semaphore rw=1;//用于实现对文件的互斥访问。表示当前是否有进程在访问共享文件
int count=0;//记录当前有几个读进程在访问文件
semaphore mutex=1;//用于保证对count变量的互斥访问
semaphore w=1; //用于实现“写优先”writer(){while(1){P(w);P(rw); //写之前“加锁”写文件。。。V(rw);//写之后“解锁”V(w);}
}reader(){while(1){P(w);P(mutex); //各读进程互斥访问countif(count==0) P(rw); //第一个读进程的读进程数+1count++; //访问文件的读进程数+1V(mutex); V(w);读文件...P(mutex); //各读进程互斥访问countcount--; //访问文件的读进程数-1if(count==0)V(rw); //最后一个读进程负责“解锁”V(mutex);}
}
五、哲学者进餐问题

五个人,必须拿左右的筷子才能吃饭避免死锁发生,解决方案:
1、可以对哲学家进程施加一些限制条件,比如最多允许四个哲学家同时进餐,这样可以保证至少有一个哲学家是可以拿到左右两只筷子的。
2、要求奇数号哲学家先拿左边的筷子,然后再拿右边的筷子,而偶数号哲学家刚好相反。用这种方法可以保证如果相邻的两个奇偶号哲学家都想吃饭,那么只会有其中一个可以拿起第一只筷子,另一个会直接阻塞。这就避免了占有一只后再等待另一只的情况。
3、仅当一个哲学家左右两只筷子都可用时才允许他抓起筷子
管程
心得:相当于C++的类,管程是数据放在private中,函数放在public中

相关文章:
操作系统之进程同异步、互斥
引入 异步性是指,各并发执行的进程以各自独立的、不可预知的速度向前推进。 但是在一定的条件之下,需要进程按照一定的顺序去执行相关进程: 举例说明1: 举例说明2: 读进程和写进程并发地运行,由于并发必然导致异步性…...
你了解这2类神经性皮炎吗?常常预示着这5类疾病!
神经性皮炎属于慢性皮肤病,患者皮肤可出现局限性苔藓样变,同时伴有阵发性瘙痒。神经性皮炎易发生在颈部两侧和四肢伸侧,中年人是高发人群。到目前为止神经性皮炎病因还并不是很明确,不过一部分病人发病前常常出现精神神经方面异常…...
二叉搜索树【Java】
文章目录 二叉搜索树的性质二叉搜索树的操作遍历查找插入删除 二叉搜索树又称为二叉排序树,是一种具有一定性质的特殊的二叉树; 二叉搜索树的性质 若它的左子树不为空,则左子树上结点的值均小于根节点的值; 若它的右子树不为空&a…...
二叉树的遍历方式
文章目录 层序遍历——队列实现分析Java完整代码 先序遍历——中左右分析递归实现非递归实现——栈实现 中序遍历——左中右递归实现非递归实现——栈实现 后续遍历——左右中递归实现非递归实现——栈加标志指针实现 总结 层序遍历——队列实现 给你二叉树的根节点 root &…...
SpringCloud01
SpringCloud01 微服务入门案例 实现步骤 导入数据 实现远程调用 MapperScan("cn.itcast.order.mapper") SpringBootApplication public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}…...
SpringBoot整合Redis实现点赞、收藏功能
前言 点赞、收藏功能作为常见的社交功能,是众多Web应用中必不可少的功能之一。而redis作为一个基于内存的高性能key-value存储数据库,可以用来实现这些功能。 本文将介绍如何使用spring boot整合redis实现点赞、收藏功能,并提供前后端页面的…...
【Java入门合集】第一章Java概述
【Java入门合集】第一章Java概述 博主:命运之光 专栏:JAVA入门 学习目标 1.理解JVM、JRE、JDK的概念; 2.掌握Java开发环境的搭建,环境变量的配置; 3.掌握Java程序的编写、编译和运行; 4.学会编写第一个Java程序&#x…...
Android无线调试操作说明
1.首先通过手机机蓝牙将jackpal.androidterm-1.0.70.apk(终端模拟器)传的设备上安装 链接: https://pan.baidu.com/s/151SzEgsX0b_VTWowzfUrsA?pwdrn75 提取码: rn75 复制这段内容后打开百度网盘手机App,操作更方便哦 2.打开这个终端模拟器,输入以下命…...
什么是 Python ?聊一聊Python程序员找工作的六大技巧
最近我一直在思考换工作的事情。因此,这段时间我会看一些题目,看一些与面试相关的内容,以便更好地准备面试。我认为无论你处于什么阶段,面试中都会有技术面试环节。无论是初级职位还是高级职位,都需要通过技术面试来检…...
RabbitMQ 01 概述
什么是消息队列 进行大量的远程调用时,传统的Http方式容易造成阻塞,所以引入了消息队列的概念,即让消息排队,按照队列进行消费。 它能够将发送方发送的信息放入队列中,当新的消息入队时,会通知接收方进行处…...
面经|曹操出行供需策略运营
1.自我介绍 面试官表示看了简历之后,表示对专业能力比较放心。想了解下对于专业能力之外,关于其他方面的介绍。 2.策略运营,除了工具之外,还有哪些能力是需要具备的 回答:主要是从做项目的维度逻辑先去回答的。 分析思…...
【Python】selenium工具
目录 1. 安装 2. 测试 3. 无头浏览器 4. 元素定位 5. 页面滑动 6. 按键、填写登录表单 7. 页面切换 Selenium是Web的自动化测试工具,为网站自动化测试而开发,Selenium可以直接运行在浏览器上,它支持所有主流的浏览器,可以接…...
实验六~Web事件处理与过滤器
1. 创建一个名为exp06的Web项目,编写、部署、测试一个ServletContext事件监听器。 BookBean代码 package org.example.beans;import java.io.Serializable;/*** Created with IntelliJ IDEA.* Description:* User: Li_yizYa* Date: 2023—04—29* Time: 18:39*/ Su…...
刷题4.28
1、 开闭原则软件实体(模块,类,方法等)应该对扩展开放,对修改关闭,即在设计一个软件系统模块(类,方法)的时候,应该可以在不修改原有的模块(修改关…...
做了一年csgo搬砖项目,还清所有债务:会赚钱的人都在做这件事 !
前段時间,在网上看到一句话:有什么事情,比窮更可怕? 有人回答说:“又忙又窮。” 很扎心,却是绝大多数人的真实写照。 每天拼死拼活的996,你有算过你的時间值多少钱? 我们来算一笔…...
线性回归模型(7大模型)
线性回归模型(7大模型) 线性回归是人工智能领域中最常用的统计学方法之一。在许多不同的应用领域中,线性回归都是非常有用的,例如金融、医疗、社交网络、推荐系统等等。 在机器学习中,线性回归是最基本的模型之一&am…...
VP记录:Codeforces Round 868 (Div. 2) A~D
传送门:CF A题:A-characteristic 构造一个只有 1 , − 1 1,-1 1,−1的数组,满足乘积为 1 1 1的数对的个数为 k k k. 发现 n n n的范围很小,考虑直接暴力枚举数组中 1 1 1的个数,记为 i i i,那么对于1的所有数对来说,我们有 i ∗ ( i − 1 ) / 2 i*(i-1)/2 i∗(i−1)/2个,然后…...
【VQ-VAE-2论文精读】Generating Diverse High-Fidelity Images with VQ-VAE-2
【VQ-VAE-2论文精读】Generating Diverse High-Fidelity Images with VQ-VAE-2 0、前言Abstract1 Introduction2 Background2.1 Vector Quantized Variational AutoEncoder3 Method3.1 Stage 1: Learning Hierarchical Latent Codes3.2 Stage 2: Learning Priors over Latent C…...
并发编程基石:管程
大家好,我是易安! 如果有人问我学习并发并发编程,最核心的技术点是什么,我一定会告诉他,管程技术。Java语言在1.5之前,提供的唯一的并发原语就是管程,而且1.5之后提供的SDK并发包,也…...
电路中噪声来源
电路包括不同的部件和芯片,所有都有可能成为噪声的来源。例如,电阻会带来热噪声,这个噪声为宽频噪声,几乎涵盖所有频率范围;运算放大器其芯片内部会产生噪声;而 ADC产生的量化噪声相较于其他器件࿰…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...
