Linux中的进程分为实时进程和普通进程
任何实时进程的优先级都要高于普通进程
进程可以分为IO消耗型和处理器消耗型
IO消耗型大部分时间都用来提交IO请求和等待IO请求
处理器耗费型进程把时间都大多用在执行代码上
在每个进程的进程控制块中都有一个域policy,用来指明该进程为何种进程,应该使用何种调度策略
若PCB中policy为SCHED_NORMAL,则说明该进程为普通进程,适用于普通进程调度策略
若PCB中的policy为SCHED_FIFO或SCHED_RR,调度器将其视为实时进程
Linux采用了两种不同的优先级范围,一种是nice值,一种是实时优先级
nice值的范围是-20~+19,默认为0,越大的nice值意味着越低的优先级
实时优先级的表示范围从0~99,值越大代表优先级越高
一个进程不能有两个优先级,实时优先级高于nice值
Linux进程的时间片,表明进程在被抢占前所能持续运行的时间
时间片太长会导致系统对交互的相应表现欠佳
时间片太短会明显增大进程切换带来的处理器耗时
此外,IO消耗型不需要太长的时间片,处理器消耗型则希望时间片越长越好
CFS的做法是允许每个进程运行一段时间,循环轮转,选择运行最少的进程作为下一个进程,而不再采用分配给每个进程时间片的做法了,CFS在所有可运行总数的基础上计算出一个进程该运行多久,而不是依靠nice值来计算时间片。nice值只是作为进程获得处理器的运行比的权重。
普通进程调度策略:完全公平调度算法
CFS调度器类的抢占时机取决于新的可运行程序消耗了多少处理器使用比,如果消耗的使用比比当前进程小,则新的进程立刻投入运行,否则,推迟其运行。
时间记账
一个进程在一个调度周期中的运行时间为:
分配给进程的运行时间 = 调度周期 * 进程权重 / 所有进程权重之和
每一个进程拥有一个vruntime,每次需要调度的时候就选运行队列中拥有最小vruntime的那个进程来运行
一个进程的实际运行时间和虚拟运行时间之间的关系为:
vruntime = 实际运行时间 * NICE_0_LOAD / 进程权重
= 实际运行时间 * 1024 / 进程权重
NICE_0_LOAD = 1024, 表示nice值为0的进程权重
进程权重越大, 运行同样的实际时间, vruntime增长的越慢,
一个进程在一个调度周期内的虚拟运行时间大小为:
vruntime = 进程在一个调度周期内的实际运行时间 * 1024 / 进程权重
= (调度周期 * 进程权重 / 所有进程总权重) * 1024 / 进程权重
= 调度周期 * 1024 / 所有进程总权重
可以看到, 一个进程在一个调度周期内的vruntime值大小是不和该进程自己的权重相关的, 所以所有进程的vruntime值大小都是一样的
进程选择
CFS利用红黑树来组织可运行队列,并利用其迅速找到vruntime值得进程,作为下一个运行进程。
实时进程调度策略:实时调度算法
对于我们的实时进程Linux一般使用实时调度算法
先进先出调度(SCHED_FIFO)
按照优先级查询就绪进程队列,当发现队列中有就绪进程时,就运行队列头位置的进程,其后,他会一直运行,除非出现下述情况
进程被具有更高优先级别进程剥夺了处理器;
进程自己因为请求资源而堵塞;
进程自己主动放弃处理器。
时间片轮转调度(SCHED_RR)
调度器按照优先级查询就绪进程队列,当发现就绪进程队列时,也是运行队列头的进程,当进程把自己的时间片消耗完后,调度器把这个进程放在队列尾,并且再选择储再队列头的进程来运行,当然前提条件是这时没有更高优先级的实时进程就绪
Linux调度时机
进程调度的时机与引起进程调度的原因和进程调度的方式有关。Linux进程调度的时机主要有:
进程状态转换的时刻,如进程中止、进程睡眠等;
可运行队列中新增加一个进程时;
当前进程的时间片用完时;
进程从系统调用返回用户态时;
内核处理完中断后,进程返回用户态时。
标签:优先级,权重,队列,调度,Linux,进程,运行
来源: https://blog.csdn.net/qq_36087425/article/details/89502310