图文并茂!谈谈进程调度那些算法 Cone
进程调度/页面置换/磁盘调度算法 xiaolinCoding
图解经典的进程调度算法 飞天小牛肉
进程调度算法是操作系统中非常重要的一部分,它决定了操作系统中各个进程的执行顺序和时间片。在单核CPU下,任何时刻都只可能有一个程序在执行,比如正在计算1*2这个程序A,那么就不能运行1+…+n这个求和程序B,这个时候程序A处于执行状态,而程序B处于非执行状态。那么就有一个需要解决的问题:我们在任意时刻到底是执行哪个程序呢?
我们运行的地铁列车,有指挥中心统一控制调度,到底由哪些地铁执行哪一天的任务,这是因为轨道等资源有限,不可能全放进去。类似到进程调度,CPU等硬件资源有限,也不可能全部一起执行。这就引出了我们的进程调度。
一般来说程序在CPU上执行有3种模式:
了解完上面的三种程序,操作系统的最大目标是让三类程序都尽可能的高效执行。
当 CPU 有一堆任务要处理时,由于其资源有限,这些事情就没法同时处理。这就需要确定某种规则来决定处理这些任务的顺序,这就是 “调度” 研究的问题。除了接下来将要说的进程调度,还有作业调度、内存调度等。
回顾一下进程的三态模型:
所谓进程调度,就是**「从进程的就绪队列(阻塞)中按照一定的算法选择一个进程并将 CPU 分配给它运行」**,以实现进程的并发执行。这是操作系统中最基本(最低级)的一种调度,在一般的操作系统中都必须配置进程调度。进程调度的频率很高,一般几十毫秒一次。
**抢占式调度算法(Preemptive Scheduling Algorithm)和非抢占式调度算法(Non-preemptive Scheduling Algorithm)**是操作系统中常用的两种调度算法,它们的核心区别在于进程在执行过程中是否可以被强制中断。
抢占式调度算法允许操作系统在进程正在执行时中断其执行并将CPU分配给其他进程。抢占式调度算法可根据进程优先级、执行时间和时间片等因素来判断是否要中断正在执行的进程,并将CPU分配给其他进程。由于抢占式调度算法能快速释放CPU资源,因此适合用于处理多任务、高优先级和实时系统。
非抢占式调度算法则不允许操作系统在正在执行的进程中强制干预,进程必须执行完才可以释放CPU。在这种情况下,进程间切换时间会比抢占式调度算法要长一些。这种算法更适合于大多数科学计算、批处理和文件处理系统,因为在这些系统中,进程的执行时间往往相对固定,且处理时间较长,这样执行中断或进程切换对系统性能的影响可能不那么明显。
因此,抢占式调度算法和非抢占式调度算法的选择应该根据系统的具体需求来进行决定,以便获得最佳性能和效率的平衡。
所谓非抢占式的意思就是,当进程正在运行时,它就会一直运行,直到该进程完成或发生某个事件发生而被阻塞时,才会把 CPU 让给其他进程。
对应的,抢占式的意思就是,当进程正在运行的时,可以被打断,把 CPU 让给其他进程。
先来先服务调度算法(First Come First Serve,FCFS):按照进程到达的先后顺序进行调度,「先到的进程就先被调度」,也就是说,等待时间越久的越优先得到服务。
优点:公平、算法实现简单
缺点:对短进程不利。排在长进程后面的短进程需要等待很长时间,短进程的响应时间太长了,用户交互体验会变差。
I/O繁忙型作业是指在进行任务处理过程中需要频繁进行I/O操作(读写文件、网络通信、数据库访问等)的进程或作业。这种类型的作业通常不需要耗费太多CPU时间来完成计算任务,但需要在等待I/O操作完成时等待,因此需要比较大的I/O操作队列来保证操作能够及时完成。
相比之下,CPU繁忙型作业则通常是需要耗费大量的CPU时间来进行计算和处理的作业,相对较少地需要进行I/O操作。
在实际应用中,I/O繁忙型作业和CPU繁忙型作业往往是相互交织的,需要合理安排作业和进程调度的顺序,以减少系统响应时间,并充分利用系统的资源。
最短作业/进程优先调度算法(Shortest Job First,SJF):「每次调度时选择当前已到达的、且运行时间最短的进程」。
最短作业优先算法和先到先服务恰好相反,先到先服务对短进程不利,而最短作业优先算法对长程不利。因为如果一直有短进程到来,那么长进程永远得不到调度,长进程有可能会饿死,处于一直等待短作业执行完毕的状态。
高响应比优先算法(Highest Response Ratio Next,HRRN):只有当前运行的进程主动放弃 CPU 时(正常/异常完成,或主动阻塞),才需要进行调度,「调度时计算所有就绪进程的响应比,为响应比最高的进程分配 CPU」。响应比 = (进程的等待时间 + 进程需要的运行时间) / 进程需要的运行时间
高响应比优先(High Response Ratio Next,HRRN)算法是一种相较于其他常见的调度算法更加优秀的作业调度算法,它能够在保证出色的响应时间和优秀的吞吐量之间求得一个平衡点。
HRRN算法的原理是计算每个作业的响应比,占用CPU时间短、等待时间长的作业具有更高的响应比。响应比的公式如下:
响应比 = (等待时间 + 服务时间) / 服务时间
其中,等待时间表示作业进入就绪队列到得到CPU时间的时间间隔,服务时间表示作业占用CPU的时间。
等待时间越长,不应该响应更慢吗?
这是一个比较容易混淆的概念,实际上等待时间长和响应速度慢并不完全等同。等待时间长指的是进程在就绪状态下等待被分配处理器运行的时间,而响应速度则指当进程获得处理器运行时,它能够快速获得结果的速度。
在作业调度中,一个进程分配到处理器上的时间往往取决于它在进程队列中等待的时间和它本身需要执行的时间,如果排在队列前面的进程载入内存,但它并不需要很长的时间就能够完成任务,那么它应当及时获得处理器时间片并得到响应,这样可以保证相应时间的快速性和效率。
在HRRN算法中,相对其他算法,等待时间长的进程(即等待在就绪队列中较长时间,但并不需要很长时间来执行)获得了更高的优先级以获得处理器时间片。这样做的好处是可以提高进程的响应速度,缩短进程的等待时间,减少平均等待时间和平均周转时间,提高系统的效率和吞吐量。
因此,等待时间长并不一定意味着响应速度慢,通过计算响应比,作业调度算法可以根据进程的特性进行合理的调度,保证进程的响应速度和等待时间的平衡,从而达到系统性能的最大化。
具体来说,HRRN算法会按照作业的响应比大小进行优先级调度,优先调度响应比高的作业,进而减少等待时间,提高响应效率。这使得HRRN算法相较于其他算法,能够更加快速地响应任务请求,减少平均等待时间和平均周转时间,提高系统响应速度和效率,同时也能避免低优先级任务永远得不到调度甚至饿死的问题。
与其他算法相比,HRRN调度算法更具有适应性和优越性。不过,HRRN算法也存在着某些问题,例如可能引起饥饿问题,即一些低响应比的长作业可能永远得不到调度等,需要根据具体情况进行优化。
抢占就是指当进程正在运行的时,可以被打断,把 CPU 让给其他进程。抢占的原则一般有三种,分别是时间片原则、优先权原则、短作业优先原则。
最短剩余时间优先(Shortest Remaining Time Next,SRTN)算法是**「最短作业优先的抢占式版本」**。
「当一个新的进程到达时,把它所需要的整个运行时间与当前进程的剩余运行时间作比较。如果新的进程需要的时间更少,则挂起当前进程,运行新的进程,否则新的进程等待。」
时间片轮转算法(Time Slice Round Robin Scheduling Algorithm)是对先来先服务算法的一种改进,其主要目的是改善短程序的响应时间。这种调度算法采用的办法就是周期性的进行执行任务的切换。比如每1秒钟切换一次执行程序,如下图。
再来看看FCFS算法中提到的例子。
A 需要运行10秒,B需要运行1秒。使用FCFS时系统平均响应时间为10.5秒。而使用时间片轮转,则A在执行1秒后,CPU切换到进程B,在执行1秒后,B结束,A接着执行9秒。这样A的响应时间是11秒,而B的响应 时间为2秒。系统的平均响应时间是6.5秒。这显然比FCFS的效率强多了,效率将近提升40%。
上面例子中,我们其实还可以发现,如果要想减少B的响应时间,可以无限制缩短时间片的间隔时间,理论上,B的响应时间可以无限接近1秒。但是反过来思考,如果时间片的轮子时间间隔增大到10S呢,那对于B来说,响应时间劣化到11秒。所以时间片轮转的时间间隔取多大的值成为了问题,这个问题可以根据系统切换进程的开销以及当前正在就绪队列的进程数可以来做判断。
但是这种算法太过于公平了,每个进程得到的执行时间都是一样的,这样就导致每个进程都不会去优化自身的执行时间,而且时间片的轮转过程中进程切换的开销也是不可忽视的。所以那还有没有更加智能的办法呢?比如有些任务就只需要0.5S,他可以快速执行完,有些任务执行60S,期间插入一个0.5S的任务,对于60S的任务时间感知也不会强烈,所以就出现了短任务优先算法
RR 调度算法对所有的进程都是相同的策略,如果用户进程太多,可能会导致内核的服务进程响应跟不上。而在操作系统中,内核进程是比用户进程重要的多的,毕竟它关乎整个系统的稳定性。
最高优先级调度算法(Highest Priority First,HPF)就是**「从就绪队列中选择最高优先级的进程进行运行」**。进程的优先级是怎么规定的呢?分为静态优先级或动态优先级:
另外,需要注意的是,最高优先级算法并非是固定的抢占式策略或非抢占式,「系统可预先规定使用哪种策略」:
多级反馈队列(Multilevel Feedback Queue)调度算法是「时间片轮转算法」和「最高优先级算法」的综合和发展。
顾名思义:
来看看,它是如何工作的:
可以发现,对于短作业可能可以在第一级队列很快被处理完。对于长作业,如果在第一级队列处理不完,可以移入下次队列等待被执行,虽然等待的时间变长了,但是运行时间也会更长了,所以该算法很好的兼顾了长短作业,同时有较好的响应时间。
讲了调度的定义、目标等概念,那么调度到底是如何进行的呢,我们来看看进程的调度过程大致概览:
进程调度算法是操作系统中非常重要的组成部分,能够控制和掌控进程的时间分配、资源分配和运行顺序。基本的进程调度算法包括先来先服务、短作业优先、高响应比优先、时间片轮转等,根据不同的应用场景和系统需求可以选用多种调度算法。除此之外,还有更多的进程调度算法如可抢占式调度算法、非抢占式调度算法、多级反馈队列调度算法等,这些调度算法的出现主要是为了更好地满足不同应用场景的需求。
在实际应用中,进程调度算法的选择需要综合考虑多方面因素,包括系统资源的使用、用户需求的响应速度、进程调度效率等。而且,随着计算机硬件技术和软件技术的发展,一些新的进程调度算法也不断涌现,这些算法一般运用了新的技术,例如人工智能等。
综上所述,进程调度算法是操作系统中不可或缺的一环,各种操作系统都需要适用合适的进程调度算法来进行任务的调度和资源管理。合适的调度算法能够提高系统性能和响应速度,优化资源的使用和管理,同时也能够为系统的安全性和可靠性保驾护航。