进程和线程的调度


一台计算机中时刻运行着非常多的进程和线程,但是CPU只有几个,为了显示出每个程序是“并行”的,就需要调度算法让它们合理的掌控CPU的时间。

因为进程线程的切换也是很耗时的,所以对于不同的系统,需要不同的调度算法,才能使调度的好处最大化。

系统分类

操作系统其实有很多类,下面只讲三类。

1、批处理系统

批处理是指用户将一批作业提交给操作系统后就不再干预,由操作系统控制它们自动运行。这种采用批量处理作业技术的操作系统称为批处理操作系统。批处理操作系统分为单道批处理系统和多道批处理系统。批处理操作系统不具有交互性,它是为了提高CPU的利用率而提出的一种操作系统。-------百度百科

也就是说,这种操作系统没有人为的干预和交互,只会自己运行。这时候可以选择以下的调度策略:

先来先服务(FCFS)
这就是最简单的调度方式,先来的先处理。这就造成其他的可能要等很久,并不理想。

最短时间优先
非抢占式,执行完一个任务后,看任务队列中谁的时间小,谁的时间小谁执行。造成大作业哭倒在厕所。

最小剩余时间优先
最短时间的抢占式版本,顾名思义,比较谁的剩余时间少。当新进来一个任务,若时间比当前执行的任务剩余时间少,就替换掉。

2、交互式系统

交互式计算机系统与操作人员以人机对话的方式一问一答,直至获得最后处理结果。采用这种方式,程序设计人员可以边设计,边调整,边修改,使错误和不足之处及时得到改正和补充。特别对于非专业的操作人员,系统能提供提示信息,逐步引导操作者完成所需的操作,得出处理结果。-------百度百科

所以说,交互式系统是需要应答的。要是应答太慢体验就糟了。有以下几种调度策略:

轮转调度
最简单且最公平的方法,给每个进程分配一个时间片。时间片耗尽时,进程会下CPU并加入到就绪队列的末尾。问题的关键是选择合适的时间片。

优先级调度
进程有轻重缓急,于是给进程设置不同的优先级,每次调度优先级最高的进程运行。当然,这样可能会导致低优先级进程饥饿。解决方案是,实行奖惩机制,高优先级进程耗尽时间片时会降低它的优先级。

多级队列
给不同优先级的进程队列,设置不同单位的时间片。同时,也实行奖惩机制,耗尽时间片会改变进程的队列级别。

3、实时系统

一个实时系统是指计算的正确性不仅取决于程序的逻辑正确性,也取决于结果产生的时间,如果系统的时间约束条件得不到满足,将会发生系统出错。
所谓“实时”,是表示“及时”,而实时系统是指系统能及时响应外部事件的请求,在规定的时间内完成对该事件的处理,并控制所有实时任务协调一致的运行。
实时系统(Real-time system,RTS)的正确性不仅依赖系统计算的逻辑结果,还依赖于产生这个结果的时间。实时系统能够在指定或者确定的时间内完成系统功能和外部或内部、同步或异步时间做出响应的系统。因此实时系统应该在事先定义的时间范围内识别和处理离散事件的能力;系统能够处理和储存控制系统所需要的大量数据。 ------百度百科

实时系统通常分为硬实时(hard real time)系统和软实时(soft real time)系统。
硬实时系统指系统要有确保的最坏情况下的服务时间,即对于事件的响应时间的截止期限是无论如何都必须得到满足。 DDL永远的神。

软实时系统就是那些从统计的角度来说,一个任务(在下面的论述中,我们将对任务和进程不作区分)能够得到有确保的处理时间,到达系统的事件也能够在截止期限到来之前得到处理,但违反截止期限并不会带来致命的错误,像实时多媒体系统就是一种软实时系统。迟交作业应该问题不大吧。

调度算法有以下几种:
最早截止时间优先(EDF)
最低松弛度优先(LLF)
emm暂时没学会

线程调度

内核线程:线程调度交给内核来完成。
用户线程:线程调度交给用户完成,在进程中设置线程的调度。内核只是调度进程,甚至不知道线程存在。

Linux 中进程、线程调度

Linux线程本质上就是进程,只是与进程间资源共享方式不同,线程间共享所有资源.除了私有的栈、程序计数器、一组进程寄存器。
SCHED_OTHER:分时调度策略。
当所有任务都是linux分时调用策略时。

  1. 创建任务指定采用分时调度策略,并指定优先级nice值(-20~19)。
  2. 将根据每个任务的nice值确定在cpu上的执行时间(counter)。
  3. 如果没有等待资源,则将该任务加入到就绪队列中。
  4. 调度程序遍历就绪队列中的任务,通过对每个任务动态优先级的计算(counter+20-nice)结果,选择计算结果最大的一个去运行,当这个时间片用完后(counter减至0)或者主动放弃cpu时,该任务将被放在就绪队列末尾(时间片用完)或等待队列(因等待资源而放弃cpu)中。
  5. 此时调度程序重复上面计算过程,转到第4步。
  6. 当调度程序发现所有就绪任务计算所得的权值都为不大于0时,重复第2步。

SCHED_FIFO:实时调度策略,先到先服务。
一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃。

它是一种实时的先进先出调用策略,且只能在超级用户下运行。这种调用策略仅仅被使用于优先级大于0的线程。它意味着,使用SCHED_FIFO的可运行线程将一直抢占使用SCHED_OTHER的运行线程J。此外SCHED_FIFO是一个非分时的简单调度策略,当一个线程变成可运行状态,它将被追加到对应优先级队列的尾部。当所有高优先级的线程终止或者阻塞时,它将被运行。对于相同优先级别的线程,按照简单的先进先运行的规则运行。我们考虑一种很坏的情况,如果有若干相同优先级的线程等待执行,然而最早执行的线程无终止或者阻塞动作,那么其他线程是无法执行的,除非当前线程调用pthread_yield之类的函数,所以在使用SCHED_FIFO的时候要小心处理相同级别线程的动作。

SCHED_RR:实时调度策略,时间片轮转。
当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平。

当所有任务都是RR:

  1. 创建任务时指定调度参数为RR,并设置任务的实时优先级和nice值(nice值将会转换为该任务的时间片的长度)。
  2. 如果没有等待资源,则将该任务加入到就绪队列中。
  3. 调度程序遍历就绪队列,根据实时优先级计算调度权值(1000+rt_priority),选择权值最高的任务使用cpu。
  4. 如果就绪队列中的RR任务时间片为0,则会根据nice值设置该任务的时间片,同时将该任务放入就绪队列的末尾。重复步骤3。
  5. 当前任务由于等待资源而主动退出cpu,则其加入等待队列中。重复步骤3。

参考文章
实时调度及相关算法
linux进程调度算法

猜你喜欢

转载自blog.csdn.net/weixin_45146520/article/details/114478030