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