操作系统实战(一)(PV经典问题之生产者与消费者)

🌈 个人主页:十二月的猫-CSDN博客
🔥 系列专栏: 🏀操作系统

💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 

目录

前言

进程互斥与同步

 题目一

题目二

题目三

题目四

题目五

题目六

题目七

题目八

题目九

题目十

题目十一

总结


前言

本系列的重点是大学本科课程《操作系统概念》。总结操作系统学习中的各类知识点,并且对各类操作系统试中可能遇到的题型和对应的解法做总结归纳。在自我复习的同时也将这份心得带给大家,希望能对大家的操作系统学习提供帮助~~

进程互斥与同步

 题目一

1、wait与signal为什么要设计成原语?

解:

原语是指不可分的操作,是具有原子性的操作。安全性:wait和signal操作是用于信号量的控制,在信号量的变化过程中不允许其他进程抢占这个进程;原子性:wait和signal操作要求是原子的,也就是说这两个操作必须是不可分的,要么全完成,要么全不完成,不存在中间状态;一致性:wait和signal操作在所有系统的信号量处理中都要使用到,原语保证其是通用的,保持在所有系统中一致

题目二

经典PV问题——有界缓存

1、存在临界资源——>定义互斥锁

2、有界缓存——>定义信号量full、empty

3、生产者代码

4、消费者代码

生产者、消费者代码编写流程:

1、找进程:确定谁是消费者,谁是生产者 

2、找主营业务:一般都是一句话带过

3、找同步约束

  •  互斥
  • 资源(计数信号量、空闲空间信号量等)
  • 限额 

2、一个输入进程向一个缓冲区中输入数据,另一个输出进程从缓冲区中取出数据输出。缓冲区中每次只能存放一个数。

解:

semaphore empty=1;// 有界缓存区大小为1
semaphore full=0;// 开始有界缓冲区不为满
semaphore mutex=1;producer{do{/*produce item*/wait(empty)wait(mutex)/*put item into the buffer*/signal(mutex)signal(full)}while(true)
}
consumer{do{wait(full)wait(mutex)/*get item from the buffer*/signal(mutex)signal(empty)/*consume the item*/}while(true)
}

题目三

有界缓存的变型

1、存在临界资源——>定义互斥锁

2、有界缓存——>定义信号量full、empty

3、输出进程只能拿加工后的数据——>进程存在执行顺序——>定义信号量去控制执行顺序

3、生产者代码

4、消费者代码

生产者:计算进程(送数)

消费者:加工进程、输出进程

输出进程和加工进程之间存在确定执行顺序 

3、三个进程共享一个缓冲区。一个计算进程送数;一个加工进程取出加工,然后将加工结果再送回缓冲区;一个输出进程将加工后的数据取出打印。缓冲区中每次只能存放一个数。

解:

semaphore empty=n;// 有界缓存区大小为n
semaphore full=0;// 开始有界缓冲区不为满
semaphore mutex=1;
semaphore processed=0;//已被加工的数据数量producer{do{/*produce item*/wait(empty)wait(mutex)/*put item into the buffer*/signal(mutex)signal(full)}while(true)
}
process{do{wait(full)wait(mutex)/*get item from the buffer*/signal(mutex)signal(empty)/*process the item*/wait(empty)wait(mutex)/*put the item into buffer*/signal(mutex)signal(full)signal(processed)}while(true)
}
consumer{do{wait(full)wait(processed)wait(mutex)/*get item from the buffer*/signal(mutex)signal(empty)/*consume the item*/}while(true)
}

题目四

4、三个进程共享一个缓冲区。一个负责向缓冲区送数;一个取偶数输出,另一个取奇数输出。缓冲区中每次只能存放一个数。

解:

semaphore empty=n;// 有界缓存区大小为n
semaphore full=0;// 开始有界缓冲区不为满
semaphore mutex=1;
semaphore odd=0;//偶数信号量
semaphore even=0;//奇数信号量producer{do{item=produce_item()wait(empty)wait(mutex)buffer.put(item)if item is evensignal(even)elsesignal(odd)signal(mutex)signal(full)}while(true)
}
consumer1{do{wait(full)wait(odd)wait(mutex)item = buffer.get()signal(mutex)signal(empty)process(item) }while(true)
}
consumer2{do{wait(full)wait(even)wait(mutex)item = buffer.get()signal(mutex)signal(empty)process(item) }while(true)
}

题目五

5、四个进程共享一个缓冲区,一个送偶数,一个送奇数,一个取偶数,一个取奇数。缓冲区中每次只能存放一个数。

解:

semaphore empty=n;// 有界缓存区大小为n
semaphore full=0;// 开始有界缓冲区不为满
semaphore mutex=1;
semaphore odd=0;//偶数信号量
semaphore even=0;//奇数信号量producer1{do{item=produce_item()wait(empty)wait(mutex)buffer.put(item)signal(even)signal(mutex)signal(full)}while(true)
}
producer2{do{item=produce_item()wait(empty)wait(mutex)buffer.put(item)signal(odd)signal(mutex)signal(full)}while(true)
}
consumer1{do{wait(full)wait(odd)wait(mutex)item = buffer.get()signal(mutex)signal(empty)process(item) }while(true)
}
consumer2{do{wait(full)wait(even)wait(mutex)item = buffer.get()signal(mutex)signal(empty)process(item) }while(true)
}

题目六

生产者-消费者问题变型——不存在生产者,利用初始化一次性完成生产

1、一次性完成生产也就不是有界缓存问题——>不需要full和empty

2、拿黑子,拿白子访问一个buffer——>互斥变量mutex

3、拿黑子和白子需要生产后才可以进行,存在先后执行顺序——>信号量white和black(也可以用普通变量来表示white和black的值,不用信号量)

4、先拿黑子,同时进程交替拿棋子,存在执行顺序——>信号量whiteTurn和blackTurn

6、围棋问题:数量相等的黑子与白子混在一起,利用两个进程分开。一个进程拣白子,另一个进程拣黑子。要求:

(1)一个进程拣了一个子,必须让另一个进程拣子;即两个进程应交替拣子;

(2)假定先拣黑子。

解:

semaphore mutex=1;
semaphore whiteTurn=0;
semaphore blackTurn=1;//先拿黑色棋子
semaphore black=n1;
semaphore white=n2;# 拣黑子的进程
black_picker {do {wait(blackTurn)          # 等待轮到拣黑子wait(black)wait(mutex)              # 获取互斥锁,确保独占访问缓冲区if buffer has black piece:item = buffer.get_black()  # 获取一个黑子process(item)        # 处理黑子signal(mutex)            # 释放互斥锁signal(whiteTurn)        # 释放白子的信号量,让白子进程拣子} while (true)
}
# 拣白子的进程
white_picker {do {wait(whiteTurn)          # 等待轮到拣白子wait(white)wait(mutex)              # 获取互斥锁,确保独占访问缓冲区if buffer has white piece:item = buffer.get_white()  # 获取一个白子process(item)        # 处理白子signal(mutex)            # 释放互斥锁signal(blackTurn)        # 释放黑子的信号量,让黑子进程拣子} while (true)
}

题目七

进程前驱图作用:

1、体现进程间的执行顺序

2、体现进程间的依赖关系

3、体现进程是否存在死锁等问题

7、画出下面4条语句的前趋图(符号“:=”是赋值的意思)
S1:a:=x+y
S2:b:=z+1
S3:c:=a-b
S4:w:=c+1

解:

题目八

N<A产品数量 – B产品数量<M——>存在同步约束中的限额

限额:(共享量对资源的使用产生限制)(这里就是利用count差值来限制)(差值限额)

1、限额意味着限额要控制进程的活动——>设定两个信号量控制进程活动

2、限额本身需要两个变量来控制——>两个变量控制进程信号量资源的释放

3、限额的检查要在实际操作之前

8、有一个仓库,可以存放X与Y两种产品,仓库的存储空间足够大,但要求:

(1)每次只能存入一种产品(X或Y);

(2)N<A产品数量 – B产品数量<M;

其中,N和M是正整数。试用“存放A”和“存放B”和wait、signal描述产品A与产品B的入库过程。

解:

semaphore mutex=0;
semaphore sem_A=0;//控制A进程的信号量
semaphore sem_B=0;//控制B进程的信号量
int countA=0;
int countB=0;//共享的限额量,全局变量storeA{wait(mutex);if countA-countB<Msignal(sem_A)signal(mutex);wait(sem_A)wait(mutex)store(A);countA++;if countA-countB>Nsignal(sem_B)signal(mutex);
}
storeB{wait(mutex)if countA-countB>Nsignal(sem_B);signal(mutex)wait(sem_B)wait(mutex)store(B);countB++;if countA-countB<Msignal(sem_A)signal(mutex)
}

注意!!

这里为了提高进程运行的效率也可以设定两个互斥信号量:1、mutex_buffer;2、mutex_count。实现对不同临界资源的限制 

1、确定生成者消费者

2、写主营业务

3、找限额控制进程信号量写上(常有两个对应的存在)

4、资源视角找同步约束(进程控制信号量)

5、找互斥

题目九

多生产者-多消费者问题+广播机制

1、多生产者-多消费者意味着实际运行需要开许多进程同步来跑

2、m个缓冲区每个放一个信息 等价于 一个缓冲区放m个信息

2、广播机制则要将一个缓冲区看为多个缓冲区,一个读进程单独享有一个缓冲区

9、进程A1、A2,……,An1通过m个缓冲区向进程B1,B2,……,Bn2不断地发送消息。发送和接收工作遵循如下规则:

(1)每个进程发送一个消息,写入一个缓冲区,缓冲区大小与消息长度一样;

(2)对每一个消息,B1,B2,……,Bn2都需各接收一次,读入各自的数据区中;

(3)m个缓冲区都满时,发送进程等待,没有可读取的消息时,接收进程等待。

试用wait与signal操作组织正确的发送和接收操作。

解:

int n2;//存在n2个读进程,这个值不是临界资源
semaphore empty[n2] = m;
semaphore full[n2] = 0;//创建n1个写进程,都用下面的代码
producer{while(1){for(int i=0;i<n2;i++){P(empty[i]);}P(mutex);消息放入缓冲区;V(mutex);for(i = 0;i<n2;i++){V(full[i]);}}
}
//创建n2个读进程,给不同的arg值和producer中的full和empty对应
consumer(void* arg){id=(int)argwhile(1){P(full[id]);P(mutex);读取缓冲区;V(mutex);V(empty[i]);}
}

题目十

本题和前面的限额问题没有区别,就是消费者消费、生产者生产需要按照队列去组织以实现FIFO

这里的限额是:差值限额

10、有一个仓库存放两种零件A和B,最大库容为各为m个。有一个车间不断地取A和B进行装配,每次各取一个。为避免零件锈蚀,遵循先入库者先出库的原则。有两组供应商分别不断地供应A和B(每次一个)。为保证齐套和合理库存,当某种零件的数量比另一种的数量超过n(n<m)个时,暂停对数量大的零件的进货,集中补充数量少的零件。试用wait和signal正确实现之。

解:

int m = 10; // 缓冲区大小
int n = 3;  // 数量差异限制
int n2;     // 读进程数量semaphore mutex = 1; // 互斥信号量
semaphore sem_A = 0; // 控制A进程的信号量
semaphore sem_B = 0; // 控制B进程的信号量
int countA = 0;      // A零件计数器
int countB = 0;      // B零件计数器void producerA() {while(1) {wait(mutex);if (countA - countB < m) {signal(sem_A);}signal(mutex);wait(sem_A);wait(mutex);// 消息放入缓冲区(存储A零件)countA++;printf("Stored A part, countA: %d\n", countA);if (countA - countB > n) {signal(sem_B);}signal(mutex);}
}void producerB() {while(1) {wait(mutex);if (countB - countA < m) {signal(sem_B);}signal(mutex);wait(sem_B);wait(mutex);// 消息放入缓冲区(存储B零件)countB++;printf("Stored B part, countB: %d\n", countB);if (countB - countA > n) {signal(sem_A);}signal(mutex);}
}void consumer(void* arg) {int id = (int)arg;while(1) {wait(sem_A); // 等待A零件wait(sem_B); // 等待B零件wait(mutex);// 从缓冲区读取零件A和B进行装配countA--;countB--;printf("Workshop assembled A and B, countA: %d, countB: %d\n", countA, countB);signal(mutex);signal(sem_A); // 通知可以放入新的A零件signal(sem_B); // 通知可以放入新的B零件}
}

题目十一

1、多生产者单消费者问题+有界缓冲+限额

2、在其他网站上看到很多人会选择增加一个guard进程来控制,但是实际上能够从限额的角度去看待这个PV问题,不需要增加一个监视进程

3、单消费者意味着不可能存在广播,没有广播需求即只有一个消费者在乖乖拿东西,那也就是说仅仅需要一个有界缓冲区即可(一个消费者只能拿一个缓冲区、一个缓冲区只能接受一个消费者。两者是一一对应关系) 

11、某高校计算机系开设网络课并安排上机实习。假定机房共有2m台机器,有2n个学生选该课,规定:

(1)每两个学生组成一组,各占一台机器,协同完成上机实习;

(2)只有一组两个学生到齐,并且此时机房有空闲机器时,该组学生才能进入机房;

(3)上机实习由一名教师检查,检查完毕,一组学生同时离开机房。

试用wait和signal正确实现之。

  • 学生是生产者
  • 教师是消费者
  • 电脑是有界缓冲区,也就是共享资源
  • 两个学生绑定为一个,也就是两台电脑绑定为一个。即有界缓存是m个资源
  • m个有界缓冲区每个一个空间可以认为是一个有界缓冲区有m个空间

解:

int m ; // 机房机器数量
int n ;  // 学生组数量(每组2个学生)semaphore machine_num=m;    // 表示有界缓冲区的数量
semaphore mutex=1;            // 保护共享资源的互斥信号量
semaphore pair_sem=0;         // 用于限额释放的信号量(配对限额)
int waiting_students = 0;     // 记录已经到达的学生数量
semaphore teacher_sem=0;      // 表示教师可以进行检查
semaphore studentGroup_sem=0; // 表示学生可以离开student{while(1){//学生过来wait(mutex)waiting_students++if(waiting_students%2==0)signal(pair_sem)signal(mutex)wait(pair_sem)wait(machine_num)wait(machine_num)wait(mutex)//操作电脑signal(mutex)signal(teacher_sem)wait(studentGroup_sem)//离开实验室signal(machine_num)signal(machine_num)}
}
teacher{wait(teacher_sem)wait(mutex)//检查学生作业signal(mutex)signal(studentGroup_sem)
}

总结

本文到这里就结束啦~~下节课我们再来进入剩下的三种调度算法
如果觉得对你有帮助,辛苦友友点个赞哦~

知识来源:操作系统概念(黑宝书)、山东大学高晓程老师PPT及课上讲解、山东大学操作系统往年题、部分考研题。不要私下外传

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

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

相关文章

在SQL中使用explode函数展开数组的详细指南

目录 简介示例1&#xff1a;简单数组展开示例2&#xff1a;展开嵌套数组示例3&#xff1a;与其他函数结合使用处理结构体数组示例&#xff1a;展开包含结构体的数组示例2&#xff1a;展开嵌套结构体数组 总结 简介 在处理SQL中的数组数据时&#xff0c;explode函数非常有用。它…

C#——装箱与拆箱详情

装箱与拆箱 装箱: 将值类型转换成引用类型的过程&#xff1b; 拆箱: 把引用类型转为值类型的过程&#xff0c;就是拆箱 装箱 拆箱

洗地机哪个品牌好?四大实力拔尖单品力荐

洗地机哪个品牌好呢&#xff1f;想必姐妹们肯定觉得保持家里清洁是非常重要的&#xff0c;但是每天打扫卫生真的会让人整个都要疯狂&#xff0c;这不&#xff0c;救星洗地机就能派上用场了&#xff0c;干垃圾湿垃圾统统都能一次清理干净。只需轻轻一推&#xff0c;就能把扫地、…

帝国cms批量取消文章审核-把已审核的文章改成未审核的方法

帝国cms很多人采集的时候&#xff0c;把文章弄成了审核过的文章&#xff0c;或者因为其他的原因&#xff0c;文章都是审核通过&#xff0c;为了seo又不能把全部文章放出来&#xff0c;所以需要把文章弄成未审核以下就是解决本问题的办法 首先来修改后台列表文件&#xff0c;自…

栈,队列,数组,链表

一.数据结构概述 数据结构是计算机底层存储,组织数据的方式。 是指数据相互之间是以什么方式排列在一起的。 数据结构是为了更加方便的管理和使用数据,需要结合具体的业务场景来进行选择。 一般情况下,精心选择的数据结构可以来更高的运行或者存储效率。 二.学好数据结构三大…

Leetcode - 132双周赛

目录 一、3174. 清除数字 二、3175. 找到连续赢 K 场比赛的第一位玩家 三、3176. 求出最长好子序列 I 四、3177. 求出最长好子序列 II 一、3174. 清除数字 本题可以使用栈来模拟&#xff0c;遇到数字弹出栈顶元素&#xff0c;遇到字母入栈。 代码如下&#xff1a; //使用字…

VMware虚拟机卡顿(虚拟机卡死)(调整所有虚拟机内存使其适应预留的主机 RAM (F)、默认进程优先级、不允许使用内存页面修整功能(M))

文章目录 设置编辑——首选项——内存——额外内存——调整所有虚拟机内存使其适应预留的主机 RAM (F)&#xff08;我把这个勾上了&#xff09;编辑——首选项——优先级——默认进程优先级虚拟机——设置——选项——高级——不允许使用内存页面修整功能(M) 参考文章&#xff…

数据结构和算法之复杂度比较

数据结构和算法之复杂度比较 参考如下网址&#xff1a;https://www.bigocheatsheet.com/ 方便快速查询 1. 复杂度比较 2. 常见数据结构复杂度 3. 常见算法复杂度

如何用命令行方式便捷组合调用 AI 工作流?

&#xff08;注&#xff1a;本文为小报童精选文章。已订阅小报童或加入知识星球「玉树芝兰」用户请勿重复付费&#xff09; 我给你演示的总结长视频、起草博客文章&#xff0c;只是其中的冰山一角。 焦虑 有些小伙伴最近跟我反馈&#xff0c;看到他人演示的样例&#xff0c;见识…

VScode中js关闭烦人的ts检查

类似如下的代码在vscode 会报错&#xff0c;我们可以在前面添加忽略检查或者错误&#xff0c;如下&#xff1a; 但是&#xff01;&#xff01;&#xff01;这太不优雅了&#xff01;&#xff01;&#xff01;&#xff0c;js代码命名没有问题&#xff0c;错在ts上面&#xff0c;…

文案生成器,免费的文案生成器

在如今这个高速发展的社会&#xff0c;内容创作已经成为许多人工作和生活中不可或缺的一部分。然而&#xff0c;随之而来的就是“内卷”。不仅要高质量的内容还要写作效率。为了在内卷中脱颖而出&#xff0c;我们就需要使用文案生成器&#xff0c;一款能够帮助我们提升写作效率…

element-plus的Tour 漫游式引导怎么去绑定Cascader 级联选择器或者它的内容 popper

首先官方例子是用的button 官方.$el这个log出来是&#xff1a; 知道是以元素为准就拿对应的元素就行 级联选择器.$el是这样的&#xff1a; 你可以移入这个元素部分去看看是哪个要用的&#xff08;好像谷歌还是狐火直接放上去就可以看到元素表示&#xff0c;但是我有时用谷歌只…

16.RedHat认证-Ansible自动化运维(中)

16.RedHat认证-Ansible自动化运维(中) 部署Ansible Ansible的Inventory文件 Inventory文件定义了ansible管理的主机&#xff0c;说白了就是Inventory文件中的内容是记录被管理的主机。 Inventory文件分为两种&#xff0c;一种是静态的Inventory文件&#xff0c;一种是动态的…

家有老人小孩,室内灰尘危害大!资深家政教你选对除尘空气净化器

哈喽&#xff0c;各位亲爱的朋友们&#xff01;今天我们来聊聊每次大扫除时最让人头疼的问题——灰尘。你有没有发现&#xff0c;两天不打扫&#xff0c;桌子上就能积上一层灰&#xff1b;阳光一照&#xff0c;地板上的灰尘都在跳舞&#xff1b;整理被子的时候&#xff0c;空气…

板凳-------第58章SOCKET:TCP/IP网络基础

58.1 互联网 互联网会将不同的计算机网络连接起来并允许位于网络中的主机相互之间进行通信。互联网的目标是隐藏不同物理网络的细节以便向互联网中的所有主机呈现一个统一的网络架构&#xff0c;TCP/IP已经成了使用最为广泛的协议套件了&#xff0c; 术语Internet被用来指将全球…

2-7 基于matlab实现声纹识别

基于matlab实现声纹识别&#xff0c;通过提取声音信号的MFCC特征&#xff0c;然后形成特征向量&#xff0c;通过训练语音&#xff0c;对测试语音进行识别&#xff0c;可以识别训练库内的声音&#xff0c;也可以识别出训练库外的声音。程序已调通&#xff0c;可直接运行。 2-7 m…

Redis持久化主从哨兵分片集群

文章目录 1. 单点Redis的问题数据丢失问题并发能力问题故障恢复问题存储能力问题 2. Redis持久化 -> 数据丢失问题RDB持久化linux单机安装Redis步骤RDB持久化与恢复示例RDB机制RDB配置示例RDB的fork原理总结 AOF持久化AOF配置示例AOF文件重写RDB与AOF对比 3. Redis主从 ->…

Meta FAIR研究新成果:图像到文本、文本到音乐的生成模型,多标记预测模型以及AI生成语音检测技术

Meta AI研究实验室(FAIR)公开发布了多项新研究成果&#xff0c;包括图像到文本和文本到音乐的生成模型&#xff0c;多词预测模型&#xff0c;以及检测AI生成语音的技术。发布的成果体现了开放性、协作、卓越和规模化等核心原则。公开早期研究工作旨在激发迭代&#xff0c;推动A…

AI写论文网站,提升论文写作效率

学术研究与论文写作是一个衡量学者专业水平的重要标准。但是&#xff0c;论文写作过程中繁琐的文献检索、资料整理、数据分析等工作往往耗时费力。幸运的是&#xff0c;随着人工智能技术的发展&#xff0c;一系列AI写论文网站应运而生&#xff0c;它们极大地提升了我们论文写作…

代码随想录刷题复习day01

day01 数组-二分查找 class Solution {public int search(int[] nums, int target) {// 左闭右闭int left 0;int right nums.length - 1;int mid 0;while (right > left) {mid left (right - left) / 2;if (nums[mid] > target)right mid - 1;else if (nums[mid]…