转自:https://blog.csdn.net/qq_34039868/article/details/104977470
目录
进程调度
1 主要功能和过程
2 必要机制
3 进程调度方式
3.1 非抢占方式(Nonpreemptive Mode)
3.2 抢占方式(Preemptive Mode)
4 进程调度队列模型
线程调度
1 进程切换的弊端
2 线程的引入
3 线程的调度
4 线程调度的优势
windows的线程调度
1 基于优先级的可抢占调度
2 Windows调度原则
Linux线程调度
进程调度的对象是进程或内核级线程,是最基本的一种调度。用于决定就绪队列中的哪个进程(或内核级线程,为叙述方便,以后只写进程)应获得处理机,然后再由分派程序执行把处理机分配给该进程的具体操作。
为了实现进程调度,应具有如下三个基本机制:
应当指出,上下文切换将花去不少的处理机时间,即使是现代计算机,每一次上下文切换大约需要花费几毫秒的时间,该时间大约可执行上千条指令。为此,现在已有通过硬件(采用两组或多组寄存器)的方法来减少上下文切换的时间。 一组寄存器供处理机在系统态时使用,另一组寄存器供应用程序使用。在这种条件下的上下文切换只需改变指针,使其指向当前寄存器组即可。
进程调度可采用下述两种调度方式。
在采用这种调度方式时,一旦把处理机分配给某进程后,不管它要运行多长时间,都一直让它运行下去,决不会因为时钟中断等原因而抢占正在运行进程的处理机,也不允许其它进程抢占已经分配给它的处理机。直至该进程完成,自愿释放处理机,或发生某事件而被阻塞时,才再把处理机分配给其他进程。
这种调度方式的优点是实现简单,系统开销小,适用于大多数的批处理系统环境。但它难以满足紧急任务的要求——立即执行,因而可能造成难以预料的后果。
这种调度方式允许调度程序根据某种原则去暂停某个正在执行的进程,将已分配给该进程的处理机重新分配给另一进程。抢占调度方式是基于一定原则的,主要有如下几条:
抢占方式的优点是,可以防止一个长进程长时间占用处理机,能为大多数进程提供更公平的服务,特别是能满足对响应时间有着较严格要求的实时任务的需求。但抢占方式比非抢占方式调度所需付出的开销较大。
进程的状态分别为:就绪(只要获取cpu资源即可执行)、执行(获取cpu正在执行)、阻塞(释放cpu资源,同时停止竞争cpu,直到被唤醒)。
系统可以把处于就绪状态的进程组织成栈、树或一个无序链表,至于到底采用其中哪种形式,则与 OS 类型和所采用的调度算法有关。在目前,通常使用FIFO的队列来存储就绪进程,每当 OS 创建一个新进程时,便将它挂在就绪队列的末尾(入队时按创建顺序)。比如对于分时系统,采用抢占式的时间片原则进行进程调度,则每个进程在执行时都可能出现以下三种情况:
调度模型如下:
在以往的OS中,进程既是资源的拥有者,也是处理器调度的基本单位。
对进程进行切换时,由于要保留当前进程的 CPU 环境和设置新选中进程的 CPU 环境,因而须花费不少的处理机时间。 换言之,由于进程是一个资源的拥有者,因而在创建、撤消和切换中,系统必须为之付出较大的时空开销。
假设以分时系统为例,设定每个进程执行的时间片为20ms,这就意味着在N核CPU满载的情况下,通常每20ms就会切换N个进程;同时,一个进程只能在一个cpu核心上运行,若同一时刻只开启了一个进程,那么其他cpu核心会处于空闲状态。
因为进程是资源的拥有者,所以在进程的切换时必须切换进程所拥有的资源,因而须花费不少的处理机时间。为了解决这个问题,引入了线程。在引入了线程的操作系统中,通常一个进程都拥有若干个线程,至少也有一个,线程成为了处理器调度的基本单位。
线程的引入使得进程仅仅是一个资源的拥有者,不再是作为调度和分派的基本单位。线程的特点如下:
线程的调度与进程的调度采用相同的调度策略,但以线程为基本单位进行调度后,对整个系统的并发能力会有一个很大的提升。下面用图来描述线程调度的好处,这里假设处理器为3核,同时OS采用抢占式的时间片原则进行线程调度。
首先,有两个进程A和B位于就绪队列中,以线程为单位进行调度:
然后,经过一次分配之后:
最后,假设线程A1,A2,B1在时间片用完后依然没有执行完,此时经过调度,会进行线程切换,线程A1,A2,B1放弃cpu并被加入就绪队列尾部,线程B2,B3,B4获得cpu资源并开始执行。
转载自论文:来源:《进程的多对多(M:N)线程模型研究》李晋。
Windows操作系统的调度模块采用的是基于优先级的可抢占调度,保证了一定的实时性支持。Windows调度代码是在内核中实现的,但是这个调度器并不是一个单独的模块或者例程,而是在调度可能触发的位置设置了一个类似触发器的函数,它被称作Windows的分发器(dispatcher)。当一个线程变为就绪态时,或者有线程离开了运行态,再或者线程的优先级和处理器亲和性等发生了改变,都会触发分发器对线程的重新调度。
Windows的优先级被分为32个级别:16个实时级别(16至31),该级别中的线程一定是最先运行,且优先级数不会发生浮动;15个可变级别(1至15),该级别中线程低于实时级别进程运行,其优先级可以根据需要由系统的负载均衡模块实时浮动,但是最高不可达到16;1个留给零页面线程的系统级别(0)。每个线程都有一个基本优先级,它是其进程优先级类别和相对线程优先级的一个函数,而线程的基本优先级根据进程基本优先级来计算。同时,线程还拥有一个当前优先级别,而调度是根据这个优先级别来进行调度判断的。在特定情况下,系统在很短的时间周期内会在动态范围(1至15)之内增加线程的优先级。在PRCB结构中有就绪线程队列整组DispatcherReadyListHead,其中每个队列都代表一个优先级,所有就绪线程就按照其优先级挂入其某个队列。
Windows的线程调度系统并没有Linux调度系统那么的复杂,其本身就遵循以下几个调度规则:
最后需要注意的是,Windows的‘剥夺式’调度中线程的调度与切换是分离的。即新调度线程并不会导致直接的线程切换。原因是如果此时是在中断服务处理阶段时,系统是不允许发生线程切换的,因为线程切换会引起堆栈的切换,这样的话中断返回时就会返回到另一个新线程的上下文中去运行。因此实际的线程切换可能会滞后一段时间到中断返回。windows的‘可剥夺’调度机制,从实时性角度上来讲还是有一定的条件限制的。
以下内容转自:https://blog.csdn.net/qq_38410730/article/details/81253686。
基于时间片原则、优先级原则的可抢占调度。
在处理器资源有限的系统中,所有进程都以轮流占用处理器的方式交叉运行。为使每个进程都有运行的机会,调度器为每个进程分配了一个占用处理器的时间额度,这个额度叫做进程的“时间片”,其初值就存放在进程控制块的counter域中。进程每占用处理器一次,系统就将这次所占用时间从counter中扣除,因为counter反映了进程时间片的剩余情况,所以叫做剩余时间片。
Linux调度的主要思想为:调度器大致以所有进程时间片的总和为一个调度周期;在每个调度周期内可以发生若干次调度,每次调度时,所有进程都以counter为资本竞争处理器控制权,counter值大者胜出,优先运行;凡是已耗尽时间片(即counter=0)的,则立即退出本周期的竞争;当所有未被阻塞进程的时间片都耗尽,那就不等了。然后,由调度器重新为进程分配时间片,开始下一个调度周期。
Linux基于时间片调度的基本思想如下图所示:
上面的调度方式主要体现的是一种公平性:如果一个进程的剩余时间片多,那么它在前期获得运行的时间片就少,为了公平性,就应该适当的赋予它更高的优先级。但是这仅仅是一个总体的原则,为了应付实际问题中的特殊状况,在上述平等原则的基础上,为了给特殊进程一些特殊照顾,在为进程分配时间片时,Linux允许用户通过一个系统调用nice()来设置参数nice影响进程的优先权。