【OS】操作系统课程笔记 第五章 并发性——互斥、同步和通信

news2025/1/6 19:30:37

并发性:并发执行的各个进程之间,既有独立性,又有制约性;

独立性:各进程可独立地向前推进;

制约性:一个进程会受到其他进程的影响,这种影响关系可能有3种形式:

  • 互斥:一种竞争关系
  • 同步:一种协作关系
  • 通信:交换信息

5.1 并发的原理

5.1.1 与时间有关的错误

现在有P1和P2两个进程共享一个变量count:

由于两个进程是异步的,所以它们执行的顺序不确定,这就会造成运行结果不可再现,除非规定它们使用共享变量的先后顺序。

5.1.2 互斥与同步的概念

进程的同步:系统中多个进程中发生的事件存在某种时序关系,需要相互合作,共同完成一项任务,即:

  • 一个进程运行到某一点时要求另一伙伴进程为它提供消息;
  • 未获得消息之前,该进程处于等待状态;
  • 获得消息后被唤醒进入就绪状态。

两个进程可以类比为接力赛中一前一后的两个队友:

进程的互斥:

互斥——不能“同时”的操作:对于系统一些共享资源,只有被释放后,才可以重新被操作;

进程互斥——进程间竞争使用不能被“同时”操作的共享资源的关系。

5.1.3 临界区与进程互斥

1. 临界资源

系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源或共享变量。

2. 临界区

在进程中涉及到临界资源的程序段叫做临界区。多个进程指针对统一资源的临界区称为相关临界区。

3. 实现各进程互斥进入临界区(互斥使用临界资源)

进程需要在临界区前加上一段用于申请资源的代码,称为进入区;在临界区后加上一段用于释放资源的代码,称为退出区。

while ( 1 )

{

        进入区代码(使用前申请);

        临界区代码(使用临界资源);

        退出区代码(释放资源);

        其余代码;

}

 4. 进入临界区(使用临界资源)的四项原则:

  1. 空闲让进:当无进程在互斥区时,任何有权使用互斥区的进程可进入;
  2. 忙则等待:不允许两个以上的进程同时进入互斥区;
  3. 有限等待:任何人进入互斥区的要求应在有限的时间内得到满足;
  4. 让权等待:处于等待状态的进程应放弃占用CPU,以使其他进程有机会得到CPU的使用权。

5. 进程互斥的解决主要有两种,分别是硬件方法和软件方法。

5.1.4 硬件支持互斥的方法

1. 中断禁用:为保证互斥,只需保证进程不被中断就可以了,通过系统中有关中断的原语即可实现。其实就是把中断这个操作当作临界资源来看。

2. 专用机器指令:就是设置一个bolt值,通过它来看是否可以使用临界资源:

5.2 信号量机制

5.2.1 信号量的概念

信号量定义

信号量是一个记录型的数据结构;

定义如下:

struct semaphore {
    int value; //信号量的值
    pointer_PCB queue;
}
semaphore s; // 定义s为信号量

P、V操作

除初始化外,仅能通过两个标准的原子操作 wait(s) 和 signal(s) 来访问信号量。这两个操作一直被称为P、V操作。

原子操作(原语):在执行上不可被中断的操作。

P、V操作定义

P(s) { // =wait(s)
    s.value--;
    if (s.value < 0)
        block(s.queue);
// 将调用该P操作的进程放入与s有关的阻塞队列
}
V(s) { // = signal(s)
    s.value++;
    if (s.value <= 0)
        wakeup(s.queue);
// 从有关s的阻塞队列唤醒一个进程放入就绪队列
}

P、V操作的含义

信号量 s 的物理含义:

  • s > 0 表示有 s 个资源可用;
  • s = 0 表示无资源可用;
  • s < 0 则 s 绝对值就是等待队列中的进程个数

P、V操作的含义:

  • P(s) :表示申请一个资源
  • V(s) :表示释放一个资源

信号量的初值应 >= 0

 信号量的使用

必须设置一次且只能设置一次初值;

初值不能为负数;

只能通过 wait(s) 和 signal(s) 来操作信号量。

如何用信号量实现进程间互斥问题?

  1. 找出临界资源,设置信号量。有几类资源就设置几个信号量,对每类资源,资源数量就是对应的信号量初值;
  2. 划分处临界区(涉及到临界资源的代码,不要人为添加条件);
  3. 临界区前加上对应信号量的P操作,临界区后加上对应信号量的V操作。

5.2.2 信号量的应用

利用信号量实现进程互斥

设P1和P2是两个进程,它们都需要使用打印机进行打印,这时可以定义一个信号量mutex,其初值为1,用于实现P1、P2进程对打印机的互斥访问:

semaphore mutex = 1; // 表示现有的打印机资源数量为1

//P1
while (true) {
    P(mutex);
    use printer;
    V(mutex);
}

//P2
while (true) {
    P(mutex);
    use printer;
    V(mutex);
}

利用信号量实现进程同步(前驱关系)

现有两个进程P1和P2,其中P1需要先执行,才能执行P2,遵循两者的执行顺序,我们可以画出进程的前驱图:

这其中,s是我们设置的信号量,其初值为0,所以在执行中,需要先进行V操作(++)再进行P操作(--),由此可以实现进程同步:

semaphore s = 0;  

//P1
{
    P1 code;
    V(s);
}

//P2
{
    P2 code;
    P(s);
}

如此可以实现先执行P1,再执行P2。

5.2.3 生产者 - 消费者问题

1. 单缓冲区:生产者进程P和消费者进程C共用一个缓冲区,P生产产品放入缓冲区,C从缓冲区取产品来消费。

单缓冲区面临的问题

单缓冲区的同步问题:

  • 当缓冲区存在空位的时候,P进程才能往里面放产品,设置信号量为empty,初值为1,表明缓冲区存在空位;
  • 当缓冲区有产品的时候,C进程才能从里面取产品,设置信号量为full,初值为0,因为缓冲区刚开始是没有产品的;

单缓冲区互斥问题:

  • P、C进程不能同时使用缓冲区

1. 单缓冲区的生产者 - 消费者问题解

semaphore empty = 1; // 表示缓冲区空位数
semaphore full = 0; //表示缓冲区产品数

//P进程
while (true) {
    produce a product;
    P(empty);
    put product in buffer;
    V(full);
}

//C进程
while (true) {
    P(full);
    get product from buffer;
    V(empty);
    consume the product;
}

2. 多缓冲区的单生产者 - 单消费者问题解

 

semaphore empty = n; // 表示缓冲区有n个空位
semaphore full = 0;

//P进程
while (true) {
    produce a product;
    P(empty);
    put product in buffer[in];
    in = (in + 1) mod n; //将产品放入缓冲区中后,in指针向后移动一位,这里的缓冲区相当于一个栈
    V(full);
}

//V进程
while (true) {
    P(full);
    get product from buffer[out];
    out = (out + 1) mod n;
    V(empty);
    consume the product;
}

3. 多生产者多消费者多个缓冲区

因为多个生产者和多个消费者都要使用到缓冲区,所以缓冲区就是我们的临界资源,为了实现生产者之间以及消费者之间的互斥关系,需要引进信号量mutex,并且其C、V操作需要放在临界区前后:

semaphore empty = n;
semaphore full = 0;
semaphore mutex = 1; // 实现同类进程间对缓冲区的互斥访问

//P进程
while (true) {
    produce a product;
    P(empty);
    P(mutex);
    put product in buffer[in];
    in = (in + 1) mod n;
    V(mutex);
    V(full);
}

//V进程
while (true) {
    P(full);
    P(mutex);
    get product from buffer[out];
    out = (out + 1) mod n;
    V(mutex);
    V(empty);
    consume the product;
}

多缓冲区面临的问题

同步:当缓冲区已放满了产品时,生产者进程必须等待;当缓冲区已空时,消费者进程应该等待;

互斥:所有进程应互斥使用缓冲区资源;

实际上,在多缓冲情况下,为提高系统并发性,只是同类进程应当互斥

在多缓冲区问题中,如果把进程P或C的mutex和另一个相邻的变量互换,就会发生死锁,死锁就是在一个进程进展到某一步时被其他进程抢占后进入阻塞状态,其他进程由于某一变量未达到条件也进入了阻塞状态。所以记住要把mutex放里面,不包含其他的变量。

多缓冲区的生产者 - 消费者问题解法2

设置两个不相干的mutex变量,这样就只是同类进程间互斥,提高了系统并发性。

如何用信号量解决进程间同步问题?

  1. 找出进程间的前驱关系;
  2. 针对每个前驱关系设置信号量,通常初值为0,具体情况要根据题目来分析;
  3. 前驱进程的后面加上对应信号量的V操作,后继进程的前面加上对应信号量的P操作。

5.2.5 读者 - 写者问题

有两组并发进程:读者和写者,共享一组数据区,为保证数据的一致性和完整性,规定如下:

  • 允许多个读者同时执行读操作
  • 不允许读者、写者同时操作
  • 不允许多个写者同时操作

若读者优先,即当写者提出了写的要求后,允许新的读者进入。则代码如下:

wrt = 1; // 表示能否写,初始可写
mutex = 1; // 实现不同读者进程的互斥访问
readcount = 1; // 表示读进程数

//读者进程
while (true) {
    P(mutex);
        readcount++;
        if(readcount == 1)
            P(wrt);
    V(mutex);
    read;
    P(mutex);
        readcount--;
        if(readcount == 0)
            V(wrt);
    V(mutex);
}

// 写者进程
while (true) {
    P(wrt);
    write;
    V(wrt);
}

信号量应用小结

P、V操作必须成对出现,有一个P操作就一定有一个V操作;

当信号量用于实现进程互斥时,对于同一信号量的P、V操作处于同一进程;

当信号量用于实现进程同步时,对于同一信号量的P、V操作处于不同进程;

如果P(S1)和P(S2)两个操作在一起,那么P操作的顺序至关重要,一个同步P操作与一个互斥P操作在一起时,同步P操作在前,互斥P操作在后,而两个V操作则无关紧要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1093330.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【从零开始学习Redis | 第三篇】在Java中操作Redis

前言&#xff1a; 本文算是一期番外&#xff0c;介绍一下如何在Java中使用Reids &#xff0c;而其实基于Java我们有很多的开源框架可以用来操作redis&#xff0c;而我们今天选择介绍的是其中比较常用的一款&#xff1a;Spring Data Redis 目录 前言&#xff1a; Spring Data…

Koordinator 协同 containerd NRI 增强容器 QoS,提升应用性能

作者&#xff1a;韩柔刚 - 阿里云&#xff0c;张康 - Intel 随着云基础业务类型和硬件资源的日益丰富&#xff0c;数据中心的资源利用率得到了显著提高&#xff0c;但也带来了资源争用的风险。在提高节点资源利用率的同时&#xff0c;确保应用程序的 QoS&#xff08;Quality o…

铜死亡+机器学习+WGCNA+分型生信思路

今天给同学们分享一篇单基因泛癌免疫实验生信文章“IGF2BP3 overexpression predicts poor prognosis and correlates with immune infiltration in bladder cancer”&#xff0c;这篇文章于2023年2月3日发表在BMC Cancer期刊上&#xff0c;影响因子为3.8。 膀胱癌是全球最常见…

利用向导创建MFC

目录 1、项目的创建&#xff1a; 2、项目的管理 &#xff1a; 3、分析以及生成的项目代码 &#xff1a; &#xff08;1&#xff09;、查看CFrame中的消息映射宏 &#xff08;2&#xff09;、自动生成事件 &#xff08;3&#xff09;、在CFrame中添加对应的鼠标处理函数 …

基于静电放电优化的BP神经网络(分类应用) - 附代码

基于静电放电优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于静电放电优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.静电放电优化BP神经网络3.1 BP神经网络参数设置3.2 静电放电算法应用 4.测试结果…

python爬虫入门详细教程-采集云南招聘网数据保存为csv文件

python爬虫之User-Agent大全、随机获取User-Agent 网站地址数据提取技术介绍采集目标流程分析python代码实现 网站地址 https://www.ynzp.com/ 这个网址特别适合新手拿来练习&#xff0c;你采集多了还有个验证码页面&#xff0c;验证码是4位数字&#xff0c;很清晰&#xff0c…

C++笔记之通用多态函数包装器std::function

C笔记之通用多态函数包装器std::function code review! 文章目录 C笔记之通用多态函数包装器std::function1.存储自由函数&#xff0c;lambda&#xff0c;std::bind 调用的结果2.存储到成员的调用3.存储到函数对象四.基本语法五.使用std::function定义函数对象六.使用std::fu…

UGUI交互组件ScrollView

一.ScrollView的结构 对象说明Scroll View挂有Scroll Rect组件的主体对象Viewport滚动显示区域&#xff0c;有Image和mask组件Content显示内容的父节点&#xff0c;只有个Rect Transform组件Scrollbar Horizontal水平滚动条Scrollbar Vertical垂直滚动条 二.Scroll Rect组件的属…

Unity角色或摄像机移动和旋转的控制脚本

该脚本挂载到需要被移动、旋转控制的物体身上&#xff0c;也可以之间挂在到摄像机上&#xff01; 挂载到摄像机上可以实现第一人称视角控制&#xff01; 挂载到物体身上&#xff0c;配合摄像机跟踪脚本可以实现&#xff0c;第三人称视角控制&#xff01; 第一人称视角 将角…

【每日一题】只出现一次的数字 II

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;位运算 写在最后 Tag 【位运算】【数组】【2023-10-15】 题目来源 137. 只出现一次的数字 II 题目解读 找出数组中仅出现一次的数字&#xff0c;其余数字仅出现三次。要求线性时间复杂度求解。 解题思路 本题的朴素…

基于nodejs+vue教学辅助管理系统

学生&#xff1b;首页、个人中心、本课程设计了线上教学辅助系统 ,学生可以此系统实现在线学习&#xff0c;作业提交管理、作业成绩管理。随着社会的快速发展&#xff0c;计算机的影响是全面且深入的。教师&#xff1a;首页、个人中心、课程信息管理、教学资料管理、作业信息管…

C++笔记之std::future的用法

C笔记之std::future的用法 code review! 文章目录 C笔记之std::future的用法1.C中std::future和std::async总是一起出现吗&#xff1f;2.主要特点和用法3.一个完整的例子4.std::future 存放的是一个结果吗&#xff1f;5.cppreference——std::future 1.C中std::future和std::a…

NCV7724DQBR2G车规级半桥电机驱动芯片-专为汽车,工业自动化应用提供完美解决方案

车规级半桥电机驱动芯片是一种用于驱动直流电机的芯片&#xff0c;常用于电动汽车、电动自行车等领域。它可以控制电机的转速和方向&#xff0c;并且具有过流保护、过温保护等功能&#xff0c;可以保证电机的安全运行。 NCV7724DQBR2G是一款车规级八通道半桥驱动器&#xff0c;…

pdf格式的简历中的照片太小,如何修改图片的大小

问题描述&#xff1a;在使用一些在线版生成软件制作简历时&#xff0c;比如使用超级简历制作的简历存在着一个照片的尺寸比较小。如何去修改pdf中的证件照大小。 解决办法&#xff1a;使用一些在线编辑pdf的软件&#xff0c;比如我随便找了一个&#xff08;在线编辑pdf&#x…

SpringCloud-Config

一、介绍 &#xff08;1&#xff09;服务注册中心 &#xff08;2&#xff09;管理各个服务上的application.yml&#xff0c;支持动态修改&#xff0c;但不会影响客户端配置 &#xff08;3&#xff09;一般将application.yml文件放在git上&#xff0c;客户端通过http/https方式…

【MST】 CF1108 F

Problem - 1108F - Codeforces 题意 思路 先看样例 这里的 MST&#xff0c;是把边排序之后合并至权值为3 权值为3的两条边&#xff0c;选其中一条即可&#xff0c;但是不能两条都选&#xff0c;这样会形成环 这启示我们&#xff0c;我们要操作的是和Kruskal的最后一条边权值…

【Excel】【latex】将EXCEL中单元格的计算关系还原为公式,用c#重构

在excel中&#xff0c;将很多个单元格&#xff0c;及其内部的公式&#xff0c;用文本的形式复制出来 Ctrl ~将 Excel 切换到公式视图&#xff0c;可以看到单元格中的公式&#xff0c;而不是公式的结果。 像平常一样复制和粘贴单元格。粘贴时&#xff0c;会看到的是单元格中的…

python+django高校教室资源预约管理系统lqg8u

技术栈 后端&#xff1a;pythondjango 前端&#xff1a;vueCSSJavaScriptjQueryelementui 开发语言&#xff1a;Python 框架&#xff1a;django/flask Python版本&#xff1a;python3.7.7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;PyChar…

力扣刷题 day14:10-14

1.超级丑数 超级丑数 是一个正整数&#xff0c;并满足其所有质因数都出现在质数数组 primes 中。 给你一个整数 n 和一个整数数组 primes &#xff0c;返回第 n 个 超级丑数 。 题目数据保证第 n 个 超级丑数 在 32-bit 带符号整数范围内。 方法一&#xff1a;动态规划 #…

P1443 马的遍历

#include <iostream> #include <queue> using namespace std; #define M 400 int arr[M 5][M 5]; typedef struct Node {int x, y; } Node; //将马能走的8个方向封装成一个二维数组 int dir[8][2] {{2, 1}, {2, -1}, {-2, 1}, {-2, -1},{1, 2}, {-1, 2}, {1, -2…