CHS_01.2.3.1+同步与互斥的基本概念
- 知识总览
- 什么是进程同步
- 什么是进程互斥
- 知识回顾
在这个小节中 我们会介绍进程同步和进程互斥相关的概念
知识总览
我们会结合一些具体的例子 让大家能够更形象的理解这两个概念 首先来看一下什么是进程同步
其实在聊进程同步之前 咱们已经接触过一个和进程同步息息相关的另外一个概念 叫做进程的异步性
那么异步性 就指各个并发的进程 他们会以各自独立的 不可预知的速度向前推进
什么是进程同步
咱们举过一个例子 就是老渣 他需要并发的执行两个约会任务
就是分别和一号约和二号约 每一个约会的进程 他又会有一系列的要求老渣来执行的指令
那么 由于这些并发执行的进程有异步性 所以这些指令的推进顺序是我们不可预知的
所以老渣有可能是这么约的 刚开始是执行一号的这个指令 一接下来执行一号的指令二也就是让老渣把新给一号
于是 由于此时老渣的心还没有给任何人 所以他会顺利的把心交给一号 那么接下来如果说切换为就是调度了第二个
约会进程的话 那么和二号的这个约会就需要执行这样的两条指定
那么这个二号的指令一就是会让老渣把心给二号 那此时由于老渣的心已经给了一号
所以二号的这一条指令让老渣把心给他 就没办法顺利的执行下去 所以这是第一种情况
那么 他还有可能是这么约的 刚开始他是和一号约 就是执行了一号的指令 一就是和老子让老渣陪他吃粉吃饭
接下来他是和二号约 然后执行了二号的指令一于是他会根据二号的这个要求 把心
给二号 那接下来如果再切换为和一号的这个约会进程的话 那么他会接着执行一号的指令二也就是让老渣把心给一号
但由于此时心已经在二号这所以一号这个也没办法顺利的执行下去 除非二号把心归还给老渣 让老渣再把这个心再分配给一号
所以可以看到 由于异步性导致了这些 这这两个并发的进程 他们的推进顺序
是我们不可预知的 可能是这样 可能是这样 还有可能是其他的一些推进方式 但是假如说
女一号这个一号 她只想做老渣的初恋 而二号只想交一个有恋爱经验的渣男
那么就意味着这个一号的指令21定是要在二号的指令一之前执行的
也就是说老渣需要先把心分配给一号 这样的话一号才是老渣的初恋吗
然后之后再把这个心回收了 再把这个心分配给二号 这样才能保证二号交到的是一个有恋爱经验的渣能
所以说 在这种情况下 我们就必须保证这两个并发执行的进程
他们之间的推进顺序 推进次序是我们可预知的 也就是要让这条指令一定需要在这条指令之前执行
那像刚才咱们举的这两个例子 第一种执行方式就是 我们就可以得到我们期待的结果
而第二种执行方式就是得不到我们期待的结果 所以其实可以看到 有的时候 这种异步性是我们必须要解决的一个问题
我们必须要保证各个进程之间的推进次序是按我们想要的那种顺序来一次推进的
那么操作系统就需要提供一个叫做进程同步的机制来实现
刚才我们所说的这种需求 在看另外一个例子之前 咱们在聊管道通进程通信的时候 讲过一种通信方式 叫做管道通信
也就是写进程先要往管道里写数据 然后当这个写数据写满之后 读进程才才可以执行读数据这样的操作 把这些数据依次取走
那写进程和读进程这两个进程 他们是并发执行的 具有异步性
所以说 写进程写数据和读进程读数据这两个操作谁发生在前 谁发生在后 其实
按照他的异步性来说 是我们不可预知的 但是在这种应用场景当中 我们又必须保证写数据发生在读数据之前 也就是这个样子
所以这个就是所谓的进程同步的问题 进程同步讨论的就是怎么解决进程异步的问题
所以同步 我们又可以把它称为直接制约关系
这种同步就是指两个或多个进程 他们有的时候可能会像这样相互协调的来完成
来合作的完成某一种工作 但是在这个合作的过程当中 又需要确定协调他们之间的这种工作次序 协经写数据在前 读数据在后 就类似于这个样子 所以这个就是所谓的进程同步的问题
那么如何实现进程同步 是咱们之后的小节会展开细聊的一个重要的知识点
在这个地方 大家只需要对进程同步是什么能有个概念 能有个理解就可以了 那么接下来咱们再聊一下什么是进程互斥
什么是进程互斥
在之前的学习当中 我们知道各个并发执行的进程 他们是需要共享这种特性来支持的
因为这些并发执行的进程肯定不可避免的需要使共享的使用一些系统资源 比如说像内存啊 像打印机 摄像头这些l设备 那么咱们之前聊到过两种
操作系统的资源共享方式互斥和同时共享这两种 其中互斥共享指的是在一个时间段内只允许一个进程访问
啊的这种资源 这种资源就只能采用互斥共享的方式 而同时共享方式就是指
允许在一个时间段内由多个进程同时对他们访问 当然这个同时指的是宏观上的 同时 微观上可能这些进程是交替的在
访问这些共享资源的 那么我们把第一种就是在一个时间段内只允许一个进程使用的 这种资源称作为临界资源
对于这些临界资源的访问 我们就需要互斥的进行 所谓互斥就是指
当某一个进程在访问这个临界资源的时候 另一个想要访问这个临界资源的进程 他必须等待
一直到当前访问这个临界资源的那个进程对这个资源的访问结束 把它释放了之后 那另一个进程才可以进去访问这个临界资源
所以这个就是所谓的互斥的概念 那一般来说实现进程的
互斥 或者说对临界资源的互斥访问可以在逻辑上分为这样的四个部分的代码 进入区 临界区 退出区和剩余区
进入区其实是负责检查此时到底能不能来访问这个临界资源
如果说可以的话 他就会对这个临界资源进行一个上锁的这样一个操作就是会设置一个
正在访问临界资源这样的一个标志 那么当他设置了这个标志之后 其他的进程
在想要访问临界资源的时候 要在进入区进行检查就会发现
此时已经有一个进程正在访问临界资源 那么其他的进程就会被阻止
进入这个临界区 访问临界资源 那这个临界区呢 就是实际用来访问临界资源的那段代码
比如说咱们在打印机要通过打印机打印输出的话 那么对打印机执行写操作这个代码
就需要写在临界区里 那退出区呢 就是负责解除刚才在进入区设置的这个正在访问临界资源的这个标志
我们可以把进入区和退出区理解成是一对一个是上锁 一个是解锁这样的一对操作
而临界区是实际用于访问临界资源的那段代码 剩余区呢就是可以做一些 在这个部分的代码当中可以做一些其他的处理 这个地方比较容易考察的是前三个部分
很多题目他可能会设置一些干扰的选项 比如说 他可能会这么说 就是说 进入区和退出区适用于访问临界资源的那段代码
那这个如果说没有注意到进入区和临界区的区别的话 那么很有可能会被误导
就错选了这样的一个错选项 所以这个地方大家稍微注意一下 另外呢 临界区还有另外一个名字 叫做临阶段 所以看到这个名字的时候也要知道
他说的其实就是临界区 那接下来我们再来思考一下 如果一个进程此时暂时没办法访问这个临界区的话
那么这个进程应该是 我们应该对这个进程做什么样的处理呢 它是应该放弃处理机 还是继续保持占用处理机
或者说 如果这个进程此时进不了临界区的的话 他有没有可能会一直进不了临界区呢
那这些都是我们在实现进程互斥的时候需要考虑的问题 那么一般来说 为了保证这些系统的整体性能
那在实现对于临界资源的互质访问 或者说实现进程互斥的时候 我们需要遵循这样的几个原则
首先 空闲让进 也就是说一个临界区 如果此时空闲没有被任何进程访问的话 那么应该允许一个
请求进入临界区的进程 立即进入临界区 这是空闲让进 第二个原则是忙则等待
当一个进程此时已经在访问临界区的话 那么另外的进程如果此时想要进入临界区 那么就就就必须让另外的那些进程等待
第三个原则叫做有限等待 也就是说 如果一个进程此时暂时进不了临界区 那么我们应该要保能够保证
这个进程在有限的时间之后就可以进入临界区 就是要保证这个进程不会发生进程饥饿的这种现象
第四个原则叫让权等待 也就是说 当一个进程此时暂时进不了临界区的话
那么这个进程应该立即释放处理机不应该一直占用 就防止进程处于一种盲等待的状态
所谓忙等待就是指这个进程暂时没办法继续往下推进了 但是这个进程还一直占用着处理机 使处理机一直处于一个忙碌的状态 没有办法
给别的进程进行服务 所以这就是进程互斥需要遵循的四个原则 在下一个小节咱们讲进程互斥的实现方法的时候
知识回顾
这几个需要遵循的原则我们还会再复习 然后会对这些原则进行一个应用 所以这个地方
暂时不用担心 那么这就是这个小节的全部内容 我们介绍了进程同步和进程互斥的
基本概念 其中进程同步又可以称之为进程之间的直接制约关系 也就是说 这些进程之间是有直接的合作的
而进程互斥又可以称作为进程之间的间接制约关系 因为进程之间并没有直接的合作关系 他们之间只是因为想要互斥的使用某一种系统
临界资源 所以才会产生这种制约关系 那么进程互斥啊的实现 在理论上我们可以
把它分为四个逻辑部分 进入区 临界区 推出去和剩余区比较长 考察的是上面这三个部分
另外呢 我们还介绍了进程互斥需要遵循的以四个原则 那么对于这四个原则的使用会在下一个小节的
推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习