进程控制是进程管理中的最基本的功能,主要包括创建新进程、终止已完成的进程、将因发生异常情况而无法继续运行的进程置于阻塞状态、负责进程运行中的状态转换功能。
简单来说:进程控制就是要实现进程状态的转换
在网络环境的应用领域主流的进程通信实现机制:客户机-服务器系统
处理机调度就是对处理机资源进行分配。
在多道批处理系统中,一个作业从提交到获得处理机执行,直至作业运行完毕,可能需要经历多级处理机调度
注:作业和进程的区别
作业(Job)是一个总任务,进程(Process)是总任务中的各个子项。
例如:课室大扫除是一项总任务,它是一个作业;
而其中擦桌子、扫地是各个子任务,擦桌子需要多次执行(每桌子执行一次),扫地只需要执行一次,这些就是在作业中调度的进程。
作业(job):是一个比程序更为广泛的概念,他不仅包含了通常的程序和数据,而且还应配有一份作业说明书,系统根据说明书对程序的运行进行控制。在批处理系统中,是以作业为基本单位从外存调入内存
作业步:在作业运行期间,每个作业都必须经过若干个相对独立,又相互关联的顺序加工步骤才能得到结果。
我们把其中的每一个加工步骤称为一个作业步,各作业步相互联系,上一个作业的输出是下一个作业的输入。
例如:一个典型作业分为:编译作业步、链接装配作业步、运行作业步
程序
数据
作业说明书
作业控制块(Job control block,JCB)
作业控制块是作业说明书在系统中生成的一张表格,
在多道批处理系统中,它是作业在系统中存在的标志,其中保存了系统对作业进行管理和调度所需的全部信息
根据JCB中的信息,检查系统中的资源能否满足作业对资源的需求,以及按照一定的调度算法,从外存的后备队列选取某些作业调入内存,并为它们创建进程、分配资源。然后再将新创建的进程排在就绪队列上等待调度。
用一个例题来解释:为什么进程在操作系统内核程序临界区中不能进行进程调度
在有的操作系统中,只允许进程主动放弃处理机,而不允许进程在运行的时候被迫的倍剥夺资源。
有的操作系统中,进程可以主动的放弃处理机,当有更紧急的任务需要处理时,也会强行剥夺处理机(被动放弃)
这样我们可以根据当前运行的进程是否可以被强行剥夺处理机资源这个问题我们引出
进程调度的方式:
注:
非抢占方式
采用了非抢占调度方式之后,还会引起进程调度的因素就只有以下几种情况
正在执行的进程运行完毕,或因发生某事件而使其无法继续运行
正在执行中的进程因提出I/O请求而暂停执行
在进程通信或同步过程中,执行了某种原语操作,如block原语
非抢占方式不能用于分时和大多数实时操作系统
抢占方式
抢占不是任意的,而是有一定的规则
优先级原则
短进程有限原则
时间片原则
既然选择了一个进程要为他分配处理机的话,我们怎么进行进程切换呢?
为了实现进程调度,在进程调度机制中,应具备如下三个基本部分:
排队器
为了提高进程调度的效率,应事先将系统中所有就绪进程按照一定的策略排列成一个或多个队列
分派器
依据进程调度程序所选定的进程,将其从就绪队列中选取出来,
然后进行从分派器到新选出进程间的上下文切换,将处理机分配给新进程
上下文切换器
对处理机进程切换操作
第一:保存当前进程上下文
第二:移除分派车程序的上下文,把新的进程的CPU现场信息装入处理机
举例1:非抢占式短进程优先(SPF,Shortest Process Frist)
举例2:最短进程优先算法的抢占式版本是最短剩余时间优先(Shortest Remaining Time Next, SRTN)算法
短作业优先算法注意的小细节
从FCFS和FJS两种算法来思考,得出一个新的算法
举例:
三种算法的比较
举例1:时间片轮转调度算法(时间片为2)
举例1:时间片轮转调度算法(时间片为5)
注:时间轮转调度算法的时间片不能太大或太小
举例1:非抢占式优先级调度算法
举例2:抢占式优先级调度算法
注:补充一些知识
在OS中引入进程之后,一方面可以使系统中的多道程序并发执行,这不仅能有效的改善资源利用率,还可以显著提高系统吞吐量,但是另一方面却使系统变得更加复杂
如果不能采取有效措施,对多个进程的运行进行妥善管理,这些进程对系统资源的无序争夺对系统造成混乱。使每次处理结果都存在不确定性,即不可再现性
进程同步的目标:对多个进程在执行次序上进行协调,使并发执行的进程能按照一定规则共享系统资源,进行相互合作,使程序的执行具有可再现性
注:许多硬件资源如:打印机、磁带机等都属于临界资源,各进程间应采取互斥方式,实现对这种资源的共享
注:不论是硬件临界资源还是软件临界资源,多个进程必须互斥的对他进行访问
人们把在每个进程值访问临界资源的那段代码称为临界区
如果能够保证各进程互斥的进入临界区,就可以实现对临界资源的互斥访问
如果一个进程暂时不能进入临界区,那么该进程是否应该一直占着处理机?该进程有没有可能一直进不了临界区?
信号量机制主要有:整型信号量机制、记录型信号量机制、AND信号量机制、信号量集机制
而我们主要介绍以下两种:整型信号量机制、记录型信号量机制
初始状态:
一开始CPU为进程P0服务:
之后CPU切换到P1进程,为P1进程服务:
然后CPU再为P2进程服务,此时没有打印机资源了,P2进程执行了block原语,进入等待队列
接下来,CPU转向了P3进程,为P3进程服务,同样在执行wait原语的时候,发现没有资源,主动执行block原语,进入等待队列队尾
然后CPU又转向了P0,为P0进行服务,P0使用完打印机之后,执行signal原语,在signal原语里面又执行力wakeup原语,用来唤醒等待队列队头的进程
P0进程执行完之后,CPU又为P2进程进行服务,P2就可以使用打印机资源,同时进行signal原语,唤醒P3进程
然后CPU又为P1进程服务,此时value加一之后大于0了,说明等待队列没有进程在等待了,所有就不需要执行wakeuo原语
最后CPU转到P3进程,为之服务,P3顺利执行到结束,系统回收打印机资源
总结:
当缓冲区当中有一个或者大于一个的空闲空间,此时就可以唤醒生产者进程,让他从阻塞态重新回到就绪队列
当消费者进程取空了缓冲区之后,消费者进程就会被阻塞
然后到生产者进程重新向缓冲区放数据的时候,消费者才会被唤醒,重新回到就绪队列
注:缓存区时临界资源,各进程必须互斥的访问
因为:如果我们系统中出现了两个生产者进程,此时生成者进程发现缓存区每个地方都是空的,可以进行放数据,一个生产者在某一个地方放数据
在并发的环境下,另一个生成者也在同样一个地方放数据,导致前者数据被后者数据覆盖的情况
如何用信号量机制(P、V操作)实现生产者、消费者进程的这些功能呢?
设置初始信号量
具体的代码实现
能否改变相邻P、V操作顺序呢?
注:生产者生产一个产品和消费者消费一个产品操作能否放到互斥信号量P、V操作之内?
逻辑上没有问题,从缓冲区取出一个产品,紧接着就使用产品
但是这就导致了临界区代码量变大,消费者在访问临界区就需要耗费更长的时间,若此时也有别的进程想要访问临界区的话,它是会被阻塞的,使得进程之间的并发度降低。
所以这两步代码不建议放到临界区之间
可以不用互斥信号量吗?
结论:即使不设置专门的互斥变量mutex,也不会出现多个进程同时访问盘子的现象
原因在于:本题的缓冲区大小为1,在任何时刻,Apple、orange、plate三个同步信号量中最多只有一个,因此在任何时候,最多只有一个进程的P操作,不会被阻塞,并顺利的进入临界区
设置信号量
代码实现:
是否需要设置一个专门的互斥信号量?
缓存区大小为1,同一时刻,四个同步信号量中至多有一个值为1,不用设置互斥信号量
如果两个写进程同时访问共享文件的话,两个写进程同时发现一块空闲空间,进而相继写入,会导致第二个写进程把第一个写进程数据覆盖了
问题分析
代码实现
解决方法:
此方法任然存在潜在问题:只要有读进程还在读,写进程就要一直阻塞等待,可能饿死,因此这种算法中,读进程是优先的
代码实现
情况1:0号哲学家,拿了左边的筷子,此时若进程切换为2号,但2号在进行mutex操作时,会被阻塞,直到0号哲学家拿到右边的筷子,并进行V(mutex)之后,2号才会被激活,执行下面代码,拿起左边和右边筷子
情况2:一开始0号,拿起了左边和右边筷子正在吃饭,此时1号也想拿起筷子,没有被mutex阻塞,但是左边还没有筷子,会发生阻塞,此时调度为2号,但是2号会被mutex阻塞,即使2号两边都有筷子
情况3:一开0号拿来左边和右边的筷子进行吃饭,当调度为4号,4号拿起了左边的筷子,但是右边没有筷子,发生阻塞
因此这种方法并不能保证只有两边的筷子都可以使用时,才允许哲学家拿起筷子
虽然信号量机制是一种既方便、又有效的进程同步机制,但每个要访问临界资源的进程都必须自备同步操作wait(S)、signal(S)。这就使得大量的同步操作分散在各个进程中,这不仅给系统的管理带来麻烦,还会因同步操作使用不当而导致系统死锁
官方定义:代表共享资源的数据结构以及由对该共享资源结构实施操作的一组过程所组成的资源管理程序共同构成了一个操作系统的资源管理模块,称之为管程
Hansan为管程下定义:一个管程定义了一个数据结构和能为并发进程所执行的一组操作,这组操作能同步进程和改善管程中的数据结构
如果一组进程中的每一个进程都在等待仅由该组进程中的其他进程才能引发的事件,那么该组进程是死锁的