一、进程的调度算法
1.FCFS(First Come First Service,先来先服务算法)
简介:按照等待时间从小到大(将等待执行的进行放入一个队列中,先进先出,也就是谁先来,谁就先被服务)送入CPU中执行。是一个非抢占式调度算法。
注:
非抢占式调度算法:除非当前进程执行完毕或者因为异常退出执行,别的进程不能打断当前正在执行的进程,必须等待正在执行的进程执行完毕才能执行下一个进程。
抢占式调度算法:可以打断当前正在执行的进程。
特点:
-
公平
-
对长作业有利,对短作业不友好(长作业执行的时候不会被打断,会直到执行结束;短作业本身只会执行较短的时间,但是FCFS的方式可能让短作业等待前面的长作业执行结束之后自己才能执行)
-
没有饥饿问题(长、短作业都会被执行,只是时间先后问题罢了)
2.SJF(Short Job First,短作业优先算法)
简介:。按照服务的时间从短到长送入CPU中执行。是一个非抢占式调度算法
特点:
- 对短作业友好,对长作业不友好(每次都是短作业先执行,不考虑长作业)
- 可能导致饥饿问题(长作业拿不到CPU执行权)
拓展:还有一种算法叫做SRTN(最短剩余时间优先算法),这种算法是一种抢占式调度算法。当进程准备就绪的时候,如果后面的进程的剩余执行时间小于当前进程,那么当前进程加入到就绪队列,下面这个拥有最短剩余时间进程开始执行(当前进程被迫放弃CUP执行权,因此是抢占式算法)。
3.HRRN(Highest Response Ratio Next,高响应比优先算法)
响应比 = (等待时间 + 要求服务时间) / 要求服务时间 注意:等待时间不是到达时间
简介:拥有高响应比的进程优先被CPU执行。是一个非抢占式的调度算法
特点:该算法综合考虑了作业/进程的等待时间和服务时间(综合了FCFS和SJF的优点)。
解释:当等待时间相同时,服务时间短的进程优先执行(SJF的优点);
当服务时间相同的时候,等待时间长的优先执行(FCFS的优点);
对长时间进程而言,如果等待的时间较长,那么其响应比就越大,就越先执行,以此避免长作业饥饿现象。
4.RR(Round-Robin,时间片轮转)
简介:CPU按照进程到达就绪队列的顺序,为这些进程分配时间片,进而服务于分配到时间片的进程(在一个时间片内没有执行完毕,则重新进入队尾)。是一个抢占式的调度算法(因为可能在一个时间片内当前进程没执行完,就要被迫切换到下一个进程)。
特点:
-
公平
-
如果时间片分配过大,那么RR就会退化成为FCFS;如果分配太小,那么会导致进程切换过于频繁。
-
不会导致饥饿问题。
-
进程间切换相对频繁,会产生一定的开销
5.PS(Priority-based Scheduling ,优先级调度算法)
简介:为进程设置对应的优先级,在调度的时候选择优先级最高的进程。有抢占式、非抢占式两种调度方式。
说明:总的来说,优先级调度算法都是根据优先级大小进行进行的,优先级高的先执行,低的后执行。抢占式与非抢占式的区别在于:当前进程A在执行过程中,就绪队列中又进入一个优先级高于当前进程的进程B,如果这时候A还未执行完就开始执行B,这就代表是抢占式的(B抢占了CPU的执行权);如果要等待A执行完再执行B,这就代表是非抢占式的。
特点:低优先级的进程会产生饥饿现象
对上述说明的详细解释:
对于抢占式的PS,如果在A运行过程中,出现了优先级高于A的B进程和优先级高于B的C进程,这时候是停止A进程调度到C进程;
对于非抢占式的PS,如果在A运行过程中,出现了优先级高于A的B进程和优先级高于B的C进程,这时候是先运行A进程,A进程结束了以后进行调度,开始执行C进程。
上面两种情况都体现了PS的核心-----优先级高的进程先运行。
补充:静态优先级与动态优先级
静态优先级:进程一经创建,其优先级就确定了,以后不能改变
动态优先级:可以动态改变进程的优先级
6.MFQS(Multilevel Feedback Queue Scheduling,多级反馈队列调度算法)
简介:多级反馈队列调度算法是对上面的算法进行折中权衡的一种调度算法。是根据先来先服务原则给就绪队列排序,为就绪队列赋予不同的优先级数,不同的时间片,按照优先级抢占CPU的一种抢占式(一般是抢占式)调度算法
多级反馈队列结构:
说明:
-
新进程首先进入1级队列,按照FCFS的原则等待被分配时间片,若用完时间片后进程还未结束,则进入下一级队列队尾。若已经在第n级队列,则放在n级队列末尾。
-
各个队列优先级从高到低,时间片大小从小到大
-
只有当K级队列为空的时候,才会为K+1级对头的进程分配时间片
-
被抢占了CPU的进程会重新放回原队列队尾
这里采用一个例子对上面的说明进行解释:
假设有三个进程,分别为P1,P2,P3。其到达时间分别是:0s,1s,5s。其运行时间分别是8s,4s,1s。
同时假设只存在三级队列,时间片大小分别为:1,2,,4
进程 | 到达时间 | 运行时间 |
---|---|---|
P1 | 0s | 8s |
P2 | 1s | 4s |
P3 | 5s | 1s |
- P1按照FCFS的原则进入一级队列,当P1执行1s(一级队列的时间片为1)后,进程P2到达。根据说明0,这时候P1进入2级队列,P2进入一级队列。
- P2在一级队列执行1s(一级队列的时间片为1)后,根据说明0,P2进入2级队列(注意P2在P1的尾部)。
- P1在二级队列执行2S(一级队列的时间片为2)后,根据说明0,P1进入3级队列。
- P2在二级队列执行,但是P2只执行1S,因为这时候P3进程到达了(已经经过了5s)。注意:根据说明3,这时候P2继续呆在2级队列,只是进入到队尾而言(P2并不会进入3级队列)
- 根据说明2,这时候P3开始在一级队列执行,1S后P3执行完毕。
- 根据说明2,开始执行P2,P2已经执行了两秒(还剩2s时间长度未执行),二级队列的时间片为2s,这时候P2执行完毕
- 1、2级队列为空后,开始执行3级队列。3级队列中只有P1(P1还剩余5s未执行,三级队列的时间片为4s),这时候P1经过CPU执行完一次后还剩1s未执行,根据说明0,P1重新进入3级队列,在一次时间片轮转后执行完毕。
优点:
- 因为新来的进程会根据FCFS的原则进入队列,因此相对公平(FCFS的优点)
- 因为短作业先进入时间片小的队列,因此短作业可以花费较少的时间完成(SJF的优点)
- 因为每个作业首先进入高优先级的一级队列,都可以得到很快的响应(RR的优点
缺点:
- 饥饿(如果下层队列有进程处于就绪状态,而此时每次新到达的进程都是短作业类型的,那么下层队列的长作业进程就拿不到CPU执行权)