Linux之进程调度

Linux属于多任务操作系统,即能同时并发地交互执行多个进程的操作系统。多任务系统又分为两类:非抢占式多任务和抢占式多任务。Linux属于抢占式。当系统中多个进程需要运行时,就牵涉到进程的调度问题。

一、几个概念

1、I/O消耗型进程和处理器消耗型进程
I/O消耗型进程:进程的大部分时间用在提交I/O请求或是等待I/O请求。所以,进程虽然处于运行状态,但是都是运行短短的一会,就开始了枯燥的等待,即阻塞。
处理器消耗型:进程把大部分时间用在执行代码上,除非被抢占。

2、进程优先级
Linux采用了两种不同的优先级范围。
第一种是nice值:(-20~19,默认为0)越大的nice值意味着更低的优先级。虽然在基于Unix的不同系统中,nice值存在不同的含义,但在Linux系统中,nice值则代表时间片的比例。随后会再详细的介绍。
第二种是实时优先级:(0~99)越高的实时优先级数值意味着进程优先级越高。

任何实时进程的优先级高于普通进程,也就是说实时优先级和nice优先级处于互不相交的两个范畴

内核中区分普通线程与实时线程是根据线程的优先级,实时线程拥有实时优先级(real-time priority),默认取值为0~99,数值越高优先级越高,而普通线程只具有nice值,nice值映射到用户层的取值范围为-20~+19,数值越高优先级越低,默认初始值为0 ,子线程会继承父线程的优先级。

3、时间片
时间片:进程在被抢占前所能程序运行的时间。
时间片太长:导致系统对交互的响应表现欠佳,让人觉得系统无法并行执行应用程序
时间片太短:明显增大进程切换带来的处理器耗时。
I/O消耗型进程:不需要更长的时间片
处理器消耗型进程:希望时间片越长越好
是否将一个进程立刻投入运行,也就是抢占当前进程,是完全由进程优先级和是否有时间片决定的。而在Linux中使用新的CFS调度器,其抢占时机取决于新的可运行程序消耗了多少处理器使用比(受nice值影响),如果消耗的使用比比当前进程小,则新进程立刻投入运行,抢占当前进程,否则推迟运行。

3、上下文切换和抢占
上下文切换就是从一个可执行程序切换到另一个可执行程序。
抢占分为用户抢占和内核抢占。
用户抢占发生在:
(1)系统调用返回用户空间时
(2)从中断处理程序返回用户空间时
内核抢占:在Linux2.6版本开始引入内核抢占,只要重新调度是安全的,内核就可以在任何时间抢占正在执行的任务。那么,什么时间重新调度是安全的?只要没有持有锁,内核就可以抢占此进程。锁是非抢占区域的标志。

二、完全公平调度算法(CFS)

CFS的出发点基于一个理念:进程调度的效果应如同系统具备一个理想中的完美多任务处理器。在这种系统中,每个进程将能获得1/n的处理器时间–n是指可运行进程的数量。同时,我们可以调度给他们无限小的时间周期,所以任何可测量的周期内,我们给予n个进程中,每个进程同样多的运行时间。

上述理想并非现实的,因为
(1)无法在一个处理器上真的同时运行多个进程
(2)每个进程运行无限小的时间周期也是不高效的----因为调度时进程抢占会带来一定的代价。
所以,CFS确定三个值:
(1)目标延迟:(最小的调度周期),越小的调度周期会带来越好的交互性,同时也更接近完美的多任务。但是必须承受更高的切换代价和更差的系统总吞吐能力。
(2)最小粒度:确定了最小周期,当同时运行的进程有无穷大时,每个进程各自所获得的处理器使用比和运行时间都趋向于0,这样无疑造成了不可接受的切换消耗,CFS为此引入了每个进程获得的时间片底线,称为最小粒度。默认情况下,这个值是1ms。
(3)时间片大小:利用nice值的相对差值,而不是绝对的nice值。例如当调度周期是20ms时,nice值分别为0和5的两进程和nice值分别为10和15的两进程分配的时间片都是15ms和5ms。

三、实时调度策略
Linux提供了两种实时调度策略:SCHED_FIFO和SCHED_RR。。而普通的、非实时性的调度策略为SCHED_NORMAL。注意,任何实时进程的优先级高于普通进程。

SCHED_FIFO
实现了一种简单,先入先出的调度算法:它不使用时间片。
一旦一个SCHED_FIFO级进程处于可执行状态,就会一直执行,直到自己受阻塞受阻塞或者显式地释放处理器为止;它不基于时间片,可以一直执行下去。只有更高优先级的SCHED_FIFO级进程或者SCHED_RR任务才能抢占SCHED_FIFO任务。

SCHED_RR
与SCHED_FIFO大体相同,只是SCHED_RR级的进程在耗尽事先分配给它的时间片后就不能再继续执行了。也就是说SCHED_RR是带有时间片的SCHED_FIFO。时间片只用来重新调度同一优先级的进程。

SCHED_NORMAL
普通线程只具有nice值,nice值映射到用户层的取值范围为-20~+19,数值越高优先级越低,默认初始值为0 ,子线程会继承父线程的优先级。

2.6之后版本的Linux中SCHED_NORMAL使用的是Linux 内核在2.6.23版本中引入的CFS(Complete Fair Scheduler)调度管理程序。CFS与之前的调度不同的是,线程的优先级与时间片之间并没有一个固定的关系,而是影响该线程在整个系统CPU运行时间中占有比例的一个因素。比如有两个线程,对应的nice值分别为0(普通线程)和+19(低优先级线程),那么普通线程将会占有19/20×100%的CPU时间,而低优先级线程将会占有1/20×100%的CPU时间(具体数值只做举例说明用,Linux内核中的计算出来的数值会不一样)。而如果同时运行的只有两个相同优先级的线程,那么他们分到的CPU时间各是50%。这样每个线程能够分配到的CPU时间占有比例跟系统当前的负载(所有处于运行态的线程数以及各线程的优先级)有关,同一个线程在他本身优先级不变的情况下分到的CPU时间占比会根据系统负载变化而发生变化,也即与时间片没有一个固定的对应关系。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值