【操作系统】进程和线程调度

转自: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线程调度


进程调度

进程调度的对象是进程或内核级线程,是最基本的一种调度。用于决定就绪队列中的哪个进程(或内核级线程,为叙述方便,以后只写进程)应获得处理机,然后再由分派程序执行把处理机分配给该进程的具体操作。

1 主要功能和过程

  1. 保存处理机的现场信息。在进程调度进行调度时,首先需要保存当前进程的处理机的现场信息,如程序计数器、多个通用寄存器中的内容等,将它们送入该进程的进程控制块(PCB)中的相应单元。
  2. 按某种算法选取进程。低级调度程序按某种算法如优先数算法、轮转法等,从就绪队列中选取一个进程,把它的状态改为运行状态,并准备把处理机分配给它。
  3. 把处理器分配给进程。由分派程序(Dispatcher)把处理器分配给进程。此时需为选中的进程恢复处理机现场,即把选中进程的进程控制块内有关处理机现场的信息装入处理器相应的各个寄存器中,把处理器的控制权交给该进程,让它从取出的断点处开始继续运行。

2 必要机制

为了实现进程调度,应具有如下三个基本机制:

  • 排队器。为了提高进程调度的效率,应事先将系统中所有的就绪进程按照一定的方式排成一个或多个队列,以便调度程序能最快地找到它。
  • 分派器(分派程序)。分派器把由进程调度程序所选定的进程,从就绪队列中取出该进程,然后进行上下文切换,将处理机分配给它。
  • 上下文切换机制。当对处理机进行切换时,会发生两对上下文切换操作。在第一对上下文切换时,操作系统将保存当前进程的上下文,而装入分派程序的上下文,以便分派程序运行;在第二对上下文切换时,将移出分派程序,而把新选进程的 CPU 现场信息装入到处理机的各个相应寄存器中。

应当指出,上下文切换将花去不少的处理机时间,即使是现代计算机,每一次上下文切换大约需要花费几毫秒的时间,该时间大约可执行上千条指令。为此,现在已有通过硬件(采用两组或多组寄存器)的方法来减少上下文切换的时间。 一组寄存器供处理机在系统态时使用,另一组寄存器供应用程序使用。在这种条件下的上下文切换只需改变指针,使其指向当前寄存器组即可。

3 进程调度方式

进程调度可采用下述两种调度方式。

3.1 非抢占方式(Nonpreemptive Mode)

在采用这种调度方式时,一旦把处理机分配给某进程后,不管它要运行多长时间,都一直让它运行下去,决不会因为时钟中断等原因而抢占正在运行进程的处理机,也不允许其它进程抢占已经分配给它的处理机。直至该进程完成,自愿释放处理机,或发生某事件而被阻塞时,才再把处理机分配给其他进程。

这种调度方式的优点是实现简单,系统开销小,适用于大多数的批处理系统环境。但它难以满足紧急任务的要求——立即执行,因而可能造成难以预料的后果。

3.2 抢占方式(Preemptive Mode)

这种调度方式允许调度程序根据某种原则去暂停某个正在执行的进程,将已分配给该进程的处理机重新分配给另一进程。抢占调度方式是基于一定原则的,主要有如下几条:

  • 优先权原则。通常是对一些重要的和紧急的作业赋予较高的优先权。当这种作业到达时,如果其优先权比正在执行进程的优先权高,便停止正在执行(当前)的进程,将处理机分配给优先权高的新到的进程,使之执行;或者说,允许优先权高的新到进程抢占当前进程的处理机。
  • 短作业(进程)优先原则。当新到达的作业(进程)比正在执行的作业(进程)明显的短时,将暂停当前长作业(进程)的执行,将处理机分配给新到的短作业(进程),使之优先执行; 或者说,短作业(进程)可以抢占当前较长作业(进程)的处理机。
  • 时间片原则。各进程按时间片轮流运行,当一个时间片用完后,便停止该进程的执行而重新进行调度。这种原则适用于分时系统、大多数的实时系统,以及要求较高的批处理系统。

抢占方式的优点是,可以防止一个长进程长时间占用处理机,能为大多数进程提供更公平的服务,特别是能满足对响应时间有着较严格要求的实时任务的需求。但抢占方式比非抢占方式调度所需付出的开销较大。

4 进程调度队列模型

进程的状态分别为:就绪(只要获取cpu资源即可执行)、执行(获取cpu正在执行)、阻塞(释放cpu资源,同时停止竞争cpu,直到被唤醒)。

系统可以把处于就绪状态的进程组织成栈、树或一个无序链表,至于到底采用其中哪种形式,则与 OS 类型和所采用的调度算法有关。在目前,通常使用FIFO的队列来存储就绪进程,每当 OS 创建一个新进程时,便将它挂在就绪队列的末尾(入队时按创建顺序)。比如对于分时系统,采用抢占式的时间片原则进行进程调度,则每个进程在执行时都可能出现以下三种情况:

  1. 任务在给定的时间片内已经完成,该进程便在释放处理机后进入完成状态;
  2. 任务在本次分得的时间片内尚未完成,OS 便将该任务再放入就绪队列的末尾;
  3. 在执行期间,进程因为某事件而被阻塞后,被 OS 放入阻塞队列。

调度模型如下:

【操作系统】进程和线程调度_第1张图片

线程调度

1 进程切换的弊端

在以往的OS中,进程既是资源的拥有者,也是处理器调度的基本单位。

对进程进行切换时,由于要保留当前进程的 CPU 环境和设置新选中进程的 CPU 环境,因而须花费不少的处理机时间。 换言之,由于进程是一个资源的拥有者,因而在创建、撤消和切换中,系统必须为之付出较大的时空开销。

假设以分时系统为例,设定每个进程执行的时间片为20ms,这就意味着在N核CPU满载的情况下,通常每20ms就会切换N个进程;同时,一个进程只能在一个cpu核心上运行,若同一时刻只开启了一个进程,那么其他cpu核心会处于空闲状态。

【操作系统】进程和线程调度_第2张图片

2 线程的引入

因为进程是资源的拥有者,所以在进程的切换时必须切换进程所拥有的资源,因而须花费不少的处理机时间。为了解决这个问题,引入了线程。在引入了线程的操作系统中,通常一个进程都拥有若干个线程,至少也有一个,线程成为了处理器调度的基本单位。

线程的引入使得进程仅仅是一个资源的拥有者,不再是作为调度和分派的基本单位。线程的特点如下:

  • 轻型实体。线程中的实体基本上不拥有系统资源,只是有一点必不可少的、 能保证其独立运行的资源。
  • 独立调度和分派的基本单位。在多线程 OS 中,线程是能独立运行的基本单位,因而也是独立调度和分派的基本单位。由于线程很“轻” ,故线程的切换非常迅速且开销小。
  • 可并发执行。多核处理器系统中,一个进程中的多个线程之间可以并发(并行)执行;同样,不同进程中的线程也能并发(并行)执行。
  • 共享进程资源。在同一进程中的各个线程都可以共享该进程所拥有的资源。
  • 在同一进程中,线程的切换不会引起进程的切换,但从一个进程中的线程切换到另一个进程中的线程时,将会引起进程的切换。

3 线程的调度

线程的调度与进程的调度采用相同的调度策略,但以线程为基本单位进行调度后,对整个系统的并发能力会有一个很大的提升。下面用图来描述线程调度的好处,这里假设处理器为3核,同时OS采用抢占式的时间片原则进行线程调度。

首先,有两个进程A和B位于就绪队列中,以线程为单位进行调度:

【操作系统】进程和线程调度_第3张图片

然后,经过一次分配之后:

【操作系统】进程和线程调度_第4张图片

最后,假设线程A1,A2,B1在时间片用完后依然没有执行完,此时经过调度,会进行线程切换,线程A1,A2,B1放弃cpu并被加入就绪队列尾部,线程B2,B3,B4获得cpu资源并开始执行。

【操作系统】进程和线程调度_第5张图片

4 线程调度的优势

  1. 一个进程内的线程可以并行执行,提高了并发性,加快了进程任务的处理。
  2. 线程基本不拥有资源,同一进程内线程的切换所费时间极小。

windows的线程调度

转载自论文:来源:《进程的多对多(M:N)线程模型研究》李晋。

1 基于优先级的可抢占调度

Windows操作系统的调度模块采用的是基于优先级的可抢占调度,保证了一定的实时性支持。Windows调度代码是在内核中实现的,但是这个调度器并不是一个单独的模块或者例程,而是在调度可能触发的位置设置了一个类似触发器的函数,它被称作Windows的分发器(dispatcher)。当一个线程变为就绪态时,或者有线程离开了运行态,再或者线程的优先级和处理器亲和性等发生了改变,都会触发分发器对线程的重新调度。

Windows的优先级被分为32个级别:16个实时级别(16至31),该级别中的线程一定是最先运行,且优先级数不会发生浮动;15个可变级别(1至15),该级别中线程低于实时级别进程运行,其优先级可以根据需要由系统的负载均衡模块实时浮动,但是最高不可达到16;1个留给零页面线程的系统级别(0)。每个线程都有一个基本优先级,它是其进程优先级类别和相对线程优先级的一个函数,而线程的基本优先级根据进程基本优先级来计算。同时,线程还拥有一个当前优先级别,而调度是根据这个优先级别来进行调度判断的。在特定情况下,系统在很短的时间周期内会在动态范围(1至15)之内增加线程的优先级。在PRCB结构中有就绪线程队列整组DispatcherReadyListHead,其中每个队列都代表一个优先级,所有就绪线程就按照其优先级挂入其某个队列。

2 Windows调度原则

Windows的线程调度系统并没有Linux调度系统那么的复杂,其本身就遵循以下几个调度规则:

  1. 严格执行按优先级的调度,只要有高优先级就绪线程的存在,低优先级线程就不能得到运行机会。
  2. 如果有多个相同优先级的就绪线程存在,则按照各线程在就绪队列中的先后次序调度。
  3. 受调度运行的线程被赋予一个时间片,只要不被更高优先级的线程剥夺,则一直运行直到时间片耗尽。但耗尽之后应当适当降低其优先级(不会低于其基准优先级),然后按照实际优先级继续挂入相应就绪队列尾部。
  4. 运行中的线程因为需要待待某个事件发生而自愿暂时放弃运行进行睡眠,这时线程并不处于就绪状态,因则不挂入就绪队列。当等待事件发生时,该线程则挂入对应优先级的就绪队列或者直接变为“剥夺者”线程。
  5. 如果线程运行过程中有更高优先级线程变为就绪线程,则当前运行线程被剥夺。

最后需要注意的是,Windows的‘剥夺式’调度中线程的调度与切换是分离的。即新调度线程并不会导致直接的线程切换。原因是如果此时是在中断服务处理阶段时,系统是不允许发生线程切换的,因为线程切换会引起堆栈的切换,这样的话中断返回时就会返回到另一个新线程的上下文中去运行。因此实际的线程切换可能会滞后一段时间到中断返回。windows的‘可剥夺’调度机制,从实时性角度上来讲还是有一定的条件限制的。

Linux线程调度

以下内容转自:https://blog.csdn.net/qq_38410730/article/details/81253686。

基于时间片原则、优先级原则的可抢占调度。

在处理器资源有限的系统中,所有进程都以轮流占用处理器的方式交叉运行。为使每个进程都有运行的机会,调度器为每个进程分配了一个占用处理器的时间额度,这个额度叫做进程的“时间片”,其初值就存放在进程控制块的counter域中。进程每占用处理器一次,系统就将这次所占用时间从counter中扣除,因为counter反映了进程时间片的剩余情况,所以叫做剩余时间片。

Linux调度的主要思想为:调度器大致以所有进程时间片的总和为一个调度周期;在每个调度周期内可以发生若干次调度,每次调度时,所有进程都以counter为资本竞争处理器控制权,counter值大者胜出,优先运行;凡是已耗尽时间片(即counter=0)的,则立即退出本周期的竞争;当所有未被阻塞进程的时间片都耗尽,那就不等了。然后,由调度器重新为进程分配时间片,开始下一个调度周期。

Linux基于时间片调度的基本思想如下图所示:

上面的调度方式主要体现的是一种公平性:如果一个进程的剩余时间片多,那么它在前期获得运行的时间片就少,为了公平性,就应该适当的赋予它更高的优先级。但是这仅仅是一个总体的原则,为了应付实际问题中的特殊状况,在上述平等原则的基础上,为了给特殊进程一些特殊照顾,在为进程分配时间片时,Linux允许用户通过一个系统调用nice()来设置参数nice影响进程的优先权。

你可能感兴趣的:(ubuntu/ros/树莓派)