进程互斥经典问题(读写者问题、理发店问题)

目录

读写者问题

问题描述

问题分析

进程互斥问题三部曲

读者写者算法实现

一、找进程——确定进程关系

二、找主营业务

三、找同步约束

a.互斥

b.资源 

c.配额 

理发店问题 

问题描述

问题分析

进程互斥问题三部曲

理发店问题算法实现

一、找进程——确定进程关系

 二、找主营业务

 三、找同步约束

a.资源

b.互斥 

c.配额 

总结


读写者问题

问题描述

有一个许多进程共享的数据区。有一些只读取这个数据区的进程(Reader)和一些只往数据区写数据的进程(Writer)。现在要写一个程序,保证这些进程的运行是安全的。

问题分析

分析问题可以发现以下这些要点:

1、读者进程彼此可以同时访问共享数据区

2、读者和写者进程不可以同时访问共享数据区

3、写者进程彼此不可以同时访问共享数据区

进程互斥问题三部曲

任何进程互斥(PV问题)都可以按照以下三步思考(来源:山东大学高晓程老师)

一、找进程——确定进程关系

二、找主营业务——抛开互斥,确定每个进程的主要任务

三、找同步约束

  1. 互斥
  2. 资源(计数信号量、空闲空间信号量等)
  3. 限额

读者写者算法实现

接下来,我们按照上面三部曲的思路来实现这个PV经典算法

一、找进程——确定进程关系

进程有两类:1、读者进程;2、写者进程

进程关系如下:

1、读者写者是互斥的

2、写者之间是互斥的

3、读者之间不是互斥的

二、找主营业务

读者进程的主营业务就是:读取reading

写者进程的主营业务就是:写入writing

(此时不考虑任何同步约束~~)

代码如下:

//写者进程
writer(){while(1){writing;}
}//读者进程
reader(){while(1){reading;}
}

三、找同步约束

a.互斥

互斥约束:1、找到临界区;2、互斥变量紧贴临界区

在上面程序的基础上增加互斥约束,如下:

//写者进程
writer(){while(1){wait(rwmutex);writing;signal(rwmutex);}
}//读者进程
reader(){while(1){wait(mutex);if(count==0){wait(rwmutex);}count++;signal(mutex);reading;wait(mutex);count--;if(count==0)signal(rwmutex);signal(mutex);}
}

关键点:

1、读者可以一起读取文件,但是读者和写者不能一起访问资源区。这表明如果没有读者访问,此时有一个读者想要访问资源区,他需要和写者竞争这个资源。一旦这个读者开始读取后,其他读者可以直接读取,不需要互斥访问。———需要一个读者和写者之间的互斥量rwmutex。

2、 由于只有第一个读者需要去竞争rwmutex,所以需要一个格外的变量count去记录目前有几个读者。

3、又由于count变量对于多个读者进程来说又是共享的变量(临界区),所以需要另外一个互斥量mutex去约束读者进程对count变量的访问

b.资源 

资源视角主要包括有界缓存问题的计数信号量、先后执行问题的同步信号量等。本题显然没有这两个信号量的约束,所以这边资源视角没有新的代码修改。

但是资源视角是一个万能视角,我们可以从资源视角来看上面的互斥:

1、rwmutex是访问资源,第一个读者进程需要和众多写者进程去竞争。只有竞争成功才可以进一步操作

2、对count的访问也是一种读者进程间的访问资源,只有每个读者进程竞争到了这个资源,才可以访问count变量,对变量进行修改

c.配额 

配额仅仅在特殊的进程互斥问题上才需要考虑,本题中并没有对配额进行限制。后续有遇到配额约束,我们再展开说说。


理发店问题 

问题描述

理发店里有一位理发师、一把理发椅和 n 把供等候理发的顾客坐的椅子。如果没有顾客,理发师便在理发椅上睡觉;当一个顾客到来时,它必须叫醒理发师;如果理发师正在理发时又有顾客来到,那么,如果有空椅子可坐,顾客就坐下来等待,否则就离开理发店。

问题分析

1、只有n把顾客坐的等待椅子,一旦椅子满了,新顾客就离开

2、理发椅子只有一个

3、没有客人理发师就睡觉,客人来了理发师才理发

进程互斥问题三部曲

任何进程互斥(PV问题)都可以按照以下三步思考(来源:山东大学高晓程老师)

一、找进程——确定进程关系

二、找主营业务——抛开互斥,确定每个进程的主要任务

三、找同步约束

  1. 互斥
  2. 资源(计数信号量、空闲空间信号量等)
  3. 限额

理发店问题算法实现

一、找进程——确定进程关系

两个进程:1、理发师进程;2、顾客进程

1、理发师和顾客进程存在先后关系,顾客来了理发师才理发

2、顾客进程之间存在互斥关系,理发椅只有一张

3、顾客进程存在上限,一旦超过上限便不再添加

 二、找主营业务

理发师:叫号+理发

顾客:取号+被理发

//理发师进程
Server(){while(1){叫号;理发;
}//顾客进程
Customer(){while(1){取号;被理发;
}

 三、找同步约束

a.资源

顾客来了,给理发师释放一个资源;理发师理完发,给顾客们释放一种资源。所以这里需要两个资源customer、server:

//默认先对信号量操作,再进行实际操作
//理发师进程
Server(){while(1){wait(customer);叫号;  //减少一个顾客数,访问临界区signal(server);理发;
}//顾客进程
Customer(){while(1){取号;  //增加一个顾客数(可能失败,所以signal在后面),访问临界区signal(customer);wait(server)被理发;
}

只有n把顾客坐的等待椅子,一旦椅子满了,新顾客就离开。所以这里需要共享变量waiting,来记录等待的顾客数目:

//默认先对信号量操作,再进行实际操作
//理发师进程
Server(){while(1){wait(customer);叫号;  //减少一个顾客数,访问临界区waiting--;  //减少一个等待顾客数,访问临界区signal(server);理发;
}//顾客进程
Customer(){while(1){if(waiting<n){取号;  //增加一个顾客数(可能失败,所以signal在后面),访问临界区signal(customer);wait(server)被理发;}else{离店;}
}
b.互斥 

对所有临界区的变量加上互斥锁

//默认先对信号量操作,再进行实际操作
//理发师进程
Server(){while(1){wait(customer);wait(mutex);叫号;  //减少一个顾客数,访问临界区waiting--;  //减少一个等待顾客数,访问临界区signal(mutex);signal(server);理发;}
}//顾客进程
Customer(){while(1){wait(mutex);  //这个wait同样也是保护if语句,所以在后面else结束if语句时也需要signalif(waiting<n){取号;  //增加一个顾客数(可能失败,所以signal在后面),访问临界区waiting++;signal(mutex);signal(customer);wait(server)被理发;}else{signal(mutex);离店;}}
}
c.配额 

配额仅仅在特殊的进程互斥问题上才需要考虑,本题中并没有对配额进行限制。后续有遇到配额约束,我们再展开说说。


总结

本文到这里就结束啦~~有时间我们再来进入其他的经典进程互斥算法
如果觉得对你有帮助,辛苦友友点个赞哦~

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

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

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

相关文章

SB-OSC,最新的 MySQL Schema 在线变更方案

目前主流的 MySQL 在线变更方案有两个&#xff1a; 基于 trigger 的 pt-online-schema-change基于 binlog 的 gh-ost 上周 Sendbird 刚开源了他们的 MySQL Schema 在线变更方案 SB-OSC: Sendbird Online Schema Change。 GitHub 上刚刚 25 颗星星&#xff0c;绝对新鲜出炉。 …

Qt Creator(2)【如何在Qt Creator中创建新工程】

阅读导航 引言一、Qt Creator开始界面介绍二、如何在Qt Creator中创建新工程1. 新建项目2. 选择项目模板3. 选择项目路径4. 选择构建系统5. 填写类信息设置界面6. 选择语言和翻译文件7. 选择Qt套件8. 选择版本控制系统9. 最终效果 三、认识Qt Creator项目内容界面1. 基本界面2.…

React Native 之 处理触摸事件(八)

React Native 提供了可以处理常见触摸手势&#xff08;例如点击或滑动&#xff09;的组件&#xff0c; 以及可用于识别更复杂的手势的完整的手势响应系统。 Button是一个简单的跨平台的按钮组件。下面是一个最简示例&#xff1a; <ButtononPress{() > {Alert.alert(你点…

go语言初识别(五)

本博客内容涉及到&#xff1a;切片 切片 1. 切片的概念 首先先对数组进行一下回顾&#xff1a; 数组定义完&#xff0c;长度是固定的&#xff0c;例如&#xff1a; var num [5]int [5]int{1,2,3,4,5}定义的num数组长度是5&#xff0c;表示只能存储5个整形数字&#xff0c…

检索模型预训练方法:RetroMAE

论文title&#xff1a;https://arxiv.org/pdf/2205.12035RetroMAE: Pre-Training Retrieval-oriented Language Models Via Masked Auto-Encoder 论文链接&#xff1a;https://arxiv.org/pdf/2205.12035 摘要 1.一种新的MAE工作流&#xff0c;编码器和解器输入进行了不同的掩…

华为OD机试【计算最接近的数】(java)(100分)

1、题目描述 给定一个数组X和正整数K&#xff0c;请找出使表达式X[i] - X[i1] … - X[i K 1]&#xff0c;结果最接近于数组中位数的下标i&#xff0c;如果有多个i满足条件&#xff0c;请返回最大的i。 其中&#xff0c;数组中位数&#xff1a;长度为N的数组&#xff0c;按照元…

软件性能测试有哪些测试类型和方法?

软件性能测试是一种通过模拟真实用户使用情况&#xff0c;评估软件系统在各种压力和负载下的表现的测试方法。在今天这个讲究效率的时代&#xff0c;软件性能测试是不可或缺的一环。它能帮助开发人员和企业发现潜在的性能问题&#xff0c;提前优化改进&#xff0c;保证软件系统…

Flutter 中的 SizeChangedLayoutNotifier 小部件:全面指南

Flutter 中的 SizeChangedLayoutNotifier 小部件&#xff1a;全面指南 在 Flutter 中&#xff0c;SizeChangedLayoutNotifier 是一种特殊的小部件&#xff0c;它用于监听其子组件尺寸的变化。当子组件的大小发生变化时&#xff0c;SizeChangedLayoutNotifier 可以通知其他组件…

动态内存管理—C语言通讯录

目录 一&#xff0c;动态内存函数的介绍 1.1 malloc和free 1.2 calloc 1.3 realloc 1.4C/C程序的内存开辟 二&#xff0c;通讯录管理系统 动态内存函数的介绍 malloc free calloc realloc 一&#xff0c;动态内存函数的介绍 1.1 malloc和free void* malloc (…

回文链表(快慢指针解法之在推进过程中反转)

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd;抱怨深处黑暗&#xff0c;不如提灯前行…

进程间通信IPC机制

进程间通信&#xff08;IPC&#xff0c;InterProcess Communication&#xff09;是指在不同进程之间传播或交换信息。IPC机制有多种方式&#xff0c;每种方式都有其特定的工作原理、应用场景以及优缺点。以下是对几种主要IPC方式的详细解释&#xff1a; 管道&#xff08;Pipe&a…

数据结构算法题day04

数据结构算法题day04 题目分析算法思想代码完整运行代码如下&#xff1a; 题目 对长度为n的顺序表L&#xff0c;编写一个时间复杂度为O(n)、空间复杂度为O(1)的算法 该算法删除线性表中所有值为X的数据元素。分析 O(n) -> 扫描一次顺序表 O(1) -> 申请常数个辅助空间 1…

代码随想录算法训练营day14|二叉树的递归遍历、二叉树的迭代遍历、二叉树的统一迭代法

二叉树的递归遍历 首先需要明确的一点是&#xff0c;前序中序和后序在二叉树的递归遍历中的区别仅在于递归函数中操作的顺序&#xff0c;前序是在遍历一个节点的左右子树前进行操作&#xff0c;中序是在遍历一个节点的左子树后进行操作再遍历右子树&#xff0c;而后序是在遍历…

C++算术运算和自增自减运算

一 引言 表示运算的符号称为运算符。 算术运算&#xff1b; 比较运算&#xff1b; 逻辑运算&#xff1b; 位运算&#xff1b; 1 算术运算 算术运算包括加、减、乘、除、乘方、指数、对数、三角函数、求余函数&#xff0c;这些都是算术运算。 C中用、-、*、/、%分别表示加、减…

【AI】AI框架项目OpenWebUI如何追加模型

【背景】 openWebUI是一个非常好用的AI框架项目&#xff0c;既可以用API形式连接各类外部AI模型&#xff0c;也可以直接连接服务器硬盘上部署的离线大模型。 简单来说&#xff0c;OpenWebUI可以用来方便地把你的本地模型变为可供所有内网人员使用的SAAS服务站点&#xff0c;并…

《当微服务遇上Ribbon:一场负载均衡的华丽舞会》

在微服务的厨房里&#xff0c;如何确保每一道服务都恰到好处&#xff1f;揭秘Spring Cloud Ribbon如何像大厨一样精心调配资源&#xff0c;让负载均衡变得像烹饪艺术一样简单&#xff01; 文章目录 Spring Cloud Ribbon 详解1. 引言微服务架构中的负载均衡需求Spring Cloud Rib…

【算法实战】每日一题:设计一个算法,用最少数量的矩形覆盖一系列宽度为d、高度为w的矩形,且使用矩形不能超出边界

题目 设计一个算法&#xff0c;用最少数量的矩形覆盖一系列宽度为d、高度为w的矩形建筑物侧墙&#xff0c;且矩形不能超出边界。 核心思路 考虑这种结构 前面递增后面一个与前面的某个高度一致&#xff0c;这时候考虑最下面的覆盖&#xff08;即都是从最下面向上覆盖&#…

redis数据类型set,zset

华子目录 Set结构图相关命令sdiff key1 [key2]sdiffstore destination key1 [key2...]sinter key1 [key2...]sinterstore destination key1 [key2...]sunion key1 [key2...]sunionstore destination key1 [key2...]smove source destination memberspop key [count]sscan key c…

Java GC问题排查的一些个人总结和问题复盘

个人博客 Java GC问题排查的一些个人总结和问题复盘 | iwts’s blog 是否存在GC问题判断指标 有的比较明显&#xff0c;比如发布上线后内存直接就起飞了&#xff0c;这种也是比较好排查的&#xff0c;也是最多的。如果单纯从优化角度&#xff0c;看当前应用是否需要优化&…

探索旅行的优惠之选,千益畅行旅游卡让旅程更省心省力!

在旅行的道路上&#xff0c;一张旅游卡往往能为您带来意想不到的便利与优惠。那么&#xff0c;对于千益畅行旅游卡&#xff0c;您是否好奇如何轻松拥有它呢&#xff1f; 首先&#xff0c;千益畅行旅游卡作为旅行者的贴心伴侣&#xff0c;为您提供了多样化的获取渠道。您可以通…