当有一堆任务要处理,但由于资源有限,这些事情没法同时处理。这就需要确定某种规则
来决定处理这些任务的顺序
,这就是“调度”研究的问题。
在多道程序系统中,进程的数量往往是多于处理机的个数的,这样不可能同时并行地处理各个进程。
而处理机调度
,就是从就绪队列中按照一定的算法选择一个进程
并将处理机分配给它运行
,以实现进程的并发执行。
由于内存空间有限,有时无法将用户提交的作业全部放入内存,因此就需要确定某种规则来决定将作业调入内存的顺序。
高级调度(作业调度)
:按一定的原则从外存上处于后备队列的作业中挑选一个或多个作业,给他们分配内存等必要资源,并建立相应的进程(建立PCB)
,以使它们获得竞争处理机的权利。
高级调度是辅存(外存)与内存之间的调度。每个作业只调入一次,调出一次。作业调入时会建立相应的PCB,作业丢调出时才撤销PCB。
高级调度主要是指调入的问题,因为只有调入的时机需要操作系统来确定,但调出的时机必然是作业运行结束才调出。
在操作系统中,作业(Job)和进程(Process)是两个不同的概念。
作业是指一组相关的任务或程序,在一个独立的逻辑单元中执行。一个作业可以由多个程序组成,这些程序可以共享某些资源,例如内存、文件和设备等。作业通常是由用户提交给操作系统,并由操作系统高级调度程序进行管理。
进程则是一个正在运行的程序实例。进程包括了程序代码、数据以及运行时堆栈等信息。在多任务环境下,操作系统可以同时运行多个进程,每个进程都有自己的地址空间和资源管理器,并且在执行过程中可以与其他进程并发地交替执行。
因此,作业和进程之间的主要区别在于:
引入了虚拟存储技术之后,可将暂时不能运行的进程调至外存等待。等它重新具备了运行条件且内存又稍有空闲时,再重新调入内存。
而这么做的目的是为了提高内存利用率
和系统吞吐量
。
暂时调到外存等待的进程状态为挂机状态
。值得注意的是,PCB并不会一起调到外存,而是会常驻内存
。PCB中会记录进程数据在外存中的存放位置,进程状态等信息,操作系统通过内存中的PCB来保持对各个进程的监控、管理。被挂机的进程PCB会被放到挂起队列中
。
中级调度(内存调度)
:就是要决定将哪个处于挂起状态的进程重新调入内存。一个进程可能会被多次调出、调入内存,因此中级调度
发生的频率
要比高级调度更高。
为减轻系统负载,提高资源利用率,暂时不执行的进程会被调到外存从而变为“挂起态“。
暂时调到外存等待的进程状态为挂起状态,挂起态又可以进一步细分为就绪挂起、阻塞挂起两种状态。
“挂起”和“阻塞”的区别:两种状态都是暂时不能获得CPU的服务,但挂起态是将进程映像调到外存去了,而阻塞态下进程映像还在内存中。
有的操作系统会把就绪挂起、阻塞挂起分为两个挂起队列,甚至会根据阻塞原因不同再把阻塞挂起进程进一步细分为多个队列。
低级调度(进程调度)
:其主要任务是按照某种方法和策略从就绪队列中选取一个进程,将处理机分配给它。
进程调度是操作系统中最基本的一种调度
,在一般操作系统中都必须配置进程调度。
进程调度的频率很高
,一般几十毫秒一次。
知识总览
进程调度
即低级调度,就是按照某种算法从就绪队列中选择一个进程为其分配处理机。
有的系统中,只允许进程主动放弃处理机。
有的系统中,进程可以主动放弃处理机,当有更紧急的任务需要处理时,也会强行剥夺处理机。
临界区:访问临界资源那段代码
临界资源:一个时间段内只允许一个进程使用的资源。各进程需要互斥地访问临界资源。
内核程序临界区
一般是用来访问某种内核数据结构
的,比如进程的就绪队列(由各就绪进程的PCB组成)
进程调度方式是为了解决:当前运行的进程是否可以被强制剥夺处理机资源
优点:实现简单,系统开销小。
缺点:无法及时处理紧急任务,适合于早期的批处理系统。
优点:可以优先处理更紧急的进程,也可实现让各进程按时间片轮流执行的功能(通过时钟中断)。适合于分时操作同,实时操作系统。
“狭义的进程调度”与“进程切换”的区别:
狭义的进程调度
指的是从就绪队列中选中一个要运行的进程
。(这个进程可以是刚刚被暂停执行的进程,也可能是另一个进程,后一种情况就需要进程切换)。
进程切换
是指让一个进程让出处理机,由另一个进程占用处理机的过程。
广义的进程调度
包含了选择一个进程和进程切换两个步骤,也就是狭义进程调度和进程切换的组合。
注:
进程切换是有代价的
,因此如果频繁的进行进程调度、切换,必然会使整个系统的效率降低,使系统大部分时间花在了进程切换上,而真正用于执行进程的时间减少。
知识总览
CPU利用率:值CPU“忙碌”的时间占总时间的比例
对于计算机来说,希望能用尽可能少的时间处理完尽可能多的作业
举例:
对于计算机用户来说,他很关心自己的作业从提交到完成期间花了多少时间。
周转时间
,是指从作业被提交给系统开始,
到作业完成为止
的这段时间间隔。
它包括四部分:
1、作业在外存后备队列上等待作业调度(高级调度)的时间
2、进程在就绪队列上等待进程调度(低级调度)的时间
3、进程在CPU上执行的时间
4、进程等待I/O操作完成的时间
后三项在一个作业的整个处理过程中,可能发生多次。
思考:有的作业运行时间短,有的作业运行时间长,因此在周转时间相同的情况下,运行时间不同的作业,给用户的感觉肯定是不一样。
对于周转时间相同的两个作业,实际运行时间长的在相同时间内被服务的时间更多,带权周转时间更小,用户满意度更高。
对于实际运行时间相同的两个作业,周转时间短的带权周转时间更小,用户满意度更高。
计算机用户希望自己的作业尽可能少的等待处理机。
等待时间
,指进程/作业处于等待处理机状态时间之和
,等待时间越长,用户满意度越低。
对于进程
来说,等待时间就是指进程建立后等待被服务的时间之和
,在等待I/O完成的期间其实进程也是在被服务的,所以不计入等待时间。
对于作业
来说,不仅要考虑建立进程后的等待时间,还要加上作业在外存后备队列中等待的时间
。
一个作业总共需要被CPU服务多久,被I/O设备服务多久一般是确定不变的,因此调度算法其实只会影响作业/进程
的等待时间。
对于计算机用户来说,会希望自己提交的请求(比如通过键盘输入了一个调试命令),尽早地开始被系统服务、回应。
响应时间
,指从用户提交请求
到首次产生响应
所用的时间。
知识总览
各种调度算法的学习思路:
1、算法思想
2、算法规则
3、这种调度算法是用于作业调度还是进程调度?
4、抢占式?非抢占式?
5、优点和缺点
6、是否会导致
饥饿
->某进程/作业长期得不到服务
对长作业有利,对短作业不利
。例题:
因为我们的FCFS算法是按照到达的先后顺序进行调度,图中P1最近到达,P2-P4到达的时间依次靠后,所以我们的调度顺序就是P1->P2->p3->p4。
剩下的平均周转时间、平均带权周转时间、平均等待时间都是将各个作业的周转时间、带权周转时间、等待时间累加求和,然后除以作业的总数量。
注意:本例中的进程都是纯计算型的进程,一个进程到达后要么在等待,要么在运行。如果是又有计算、又有I/O操作的进程,其等待时间就是周转时间-运行时间-I/O操作的时间。
注意:
1、如果题目中未特别说明,所提到的“短作业/进程优先算法”默认是非抢占式的。
2、很多书上都会说“SJF调度算法的平均等待时间、平均周转时间最少”,严格来说,这个表述是错误的,不严谨的。之前的例子表明,最短剩余时间优先算法得到的平均等待时间、平均周转时间还要更少。
应该加上一个条件“在
所有进程同时可运行
时,采用SJF调度算法的平均等待时间、平均周转时间最少。"3、虽然严格来说,SJF的平均等待时间、平均周转时间不一定最少,但相比于其他算法(如FCFS),SJF依然可以获得较少的平均等待时间、平均周转时间。
思考
Highest Response Ratio Next
HRRN高响应比优先算法是一种用于进程调度的算法,该算法考虑了进程的等待时间和服务时间,根据这两个因素计算出每个进程的响应比,然后选择具有最高响应比的进程进行运行。
计算响应比的公式:
响应比=(等待时间+服务时间)/服务时间
其中,等待时间是指进程在就绪队列中等待的时间,服务时间是指进程执行需要的时间。
当有多个进程处于就绪状态时,HRRN高响应比优先算法会选择响应比最高的进程进行执行。此时,如果有新的进程到来,那么它的响应比将与原有的进程相比较,如果其响应比更高,则会被插入到就绪队列的前列,以保证进程的响应速度和效率。
使用HRRN高响应比算法可以有效地提高系统的吞吐量和响应速度,因为它能够尽可能地满足进程的需求,并兼顾不同进程之间的公平性。
时间片轮转(Round-Robin)调度算法是一种基于时间片的CPU调度算法,它将CPU分配给各个进程,并按照一定时间间隔进行切换。整个系统的时间被分成一段段的时间片,在每个时间片内,CPU只执行一个进程,并在时间片结束时强制进行上下文切换,将CPU分配给另一个等待执行的进程。
优点:这种算法能够保证所有就绪进程都能够得到公平的机会占用CPU资源,并且可以有效地避免某些进程过长占用CPU导致其他进程无法运行的情况。同时,由于每个时间片较短,因此对于交互式进程或需要及时响应的应用程序来说,用户体验也更加流畅。
缺点:如果时间片设置得太小,就会导致频繁的上下文切换,增加了系统开销;而如果时间片设置得太大,则可能会影响系统响应性能。
1、将所有进程按照到达时间
排成一个队列,对于相同到达时间的进程,按照进程ID排序。
2、将每个进程的状态设置为就绪态
,并将其插入就绪队列尾部
。
3、从就绪队列头部
取出一个进程,将其状态设置为运行状态,并将其放入CPU中执行。
4、如果该进程执行完毕
,则将其从进程列表和就绪队列中删除
。
5、如果该进程还没有执行完毕,但已经达到了时间片末尾
,则将其状态设置为就绪状态
,并将其重新插入就绪队列尾部。
6、如果该进程还没有执行完毕,并且也没有到达时间片末尾
,则将其状态设置为阻塞状态
,并将其从CPU中移除。
7、在每个时间片结束
时,检查是否有新的进程
到达。如果有,则将其加入就绪队列尾部。
8、重复步骤3到步骤7,直到所有进程都执行完毕。
时间片轮转调度算法和FCFS算法的主要区别在于任务的处理顺序
和时间分配方式
。
优先级调度算法(Priority Scheduling)是一种进程调度算法,它根据每个进程的优先级来决定下一个要执行的进程。每个进程被赋予一个优先级,通常是一个整数值。具有较高优先级的进程将比具有较低优先级的进程先被调度执行。
在优先级调度算法中,当一个新的进程到达时,它将被插入到就绪队列中,并与现有的进程进行优先级比较。如果新进程的优先级比当前正在运行的进程的优先级高,那么进程调度器将抢占正在运行的进程,让新进程先执行。否则,当前进程继续执行直到完成或者被阻塞。当一个进程完成或者阻塞时,进程调度器将从就绪队列中选取优先级最高的进程作为下一个要执行的进程。
需要注意的是,在实现优先级调度算法时需要考虑如何避免低优先级进程发生饥饿(starvation)问题。为了解决这个问题,可以采用 Aging 技术,即随着时间的推移,逐渐增加低优先级进程的优先级,从而确保所有进程都有机会得到执行。
优先级调度算法的优点是能够使得优先级高的进程尽快得到执行,从而提高系统的响应速度和效率。然而,它也存在低优先级进程饥饿的问题,因此需要特殊处理以确保所有进程都有机会得到执行。
非抢占式优先级调度算法是一种进程调度算法,其执行过程如下:
需要注意的是,非抢占式优先级调度算法不能够强制抢占正在运行的进程,这意味着如果当前正在运行的进程的优先级比其他就绪进程低,则其他进程可能需要等待较长时间才能获得CPU时间片。为了避免这种情况,通常需要采取一些措施,如动态调整进程优先级或引入“反馈式调度算法”。
抢占式优先级调度算法是一种进程调度算法,相较于非抢占式优先级调度算法,其最大的特点就是能够强制抢占正在运行的进程。其执行过程如下:
需要注意的是,抢占式优先级调度算法可能会出现“饥饿”现象,即某些低优先级进程长时间无法获得CPU时间片。为了避免这种情况,通常需要采取一些措施,如引入时间片轮转机制或者动态提高低优先级进程的优先级。
多级反馈队列调度算法(multilevel feedback queue scheduling algorithm)是一种常见的进程调度算法,主要用于优化系统资源的利用率和响应时间。
该算法将进程队列分为多个等级,每个等级对应不同的处理器时间片大小。进程首先被放入最高优先级的队列中,如果在该队列中没有得到处理器执行,则进程被移动到次高优先级的队列,以此类推,直到进程得到处理器执行或者进入最低优先级的队列后仍未能得到处理器执行并被阻塞。
如果一个进程在队列中等待的时间超过一定时间(也称为时间片),则它会被移动到更高优先级的队列中,以便尽快得到处理器执行。此外,如果一个进程需要等待某些资源才能继续执行,那么它会被移动到较低优先级的队列中,以便让其他进程先得到处理器执行。
这种调度算法可以有效地避免进程长时间占用处理器而导致其他进程无法执行的情况,并且可以根据实际情况调整各个队列的优先级,使系统的性能得到最优化。
假设有以下三个进程,每个进程需要运行10个时间片:
进程 | 到达时间 | 优先级 |
---|---|---|
P1 | 0 | 1 |
P2 | 2 | 2 |
P3 | 4 | 3 |
现在,我们使用三个就绪队列进行调度,每个队列的时间片分别为10、20和40。执行过程如下: