linux 调度策略?k8s调度策略

linux线程调度策略

从Linux 2.6.23起,默认调度器为CFS(Completely Fair Scheduler),取代了O(1)调度器。CFS调度策略的详细信息可在sched-design-CFS中查阅,且cgroup的CPU调度为CFS扩展的一部分。

内核使用调度器决定下一个CPU周期执行的线程。每个线程包含调度策略与静态优先级sched_priority,调度器基于系统上所有线程的策略与优先级来决定调度。

对于SCHED_OTHER、SCHED_IDLE、SCHED_BATCH策略的线程,sched_priority不影响调度结果,且必须设为0。实时策略SCHED_FIFO与SCHED_RR线程的sched_priority取值为1至99,实时线程优先级高于普通线程。

调度器为每个sched_priority维护运行线程列表。调度器查看非空且优先级最高的列表,选择首部元素作为下个执行线程。

调度策略决定了如何根据静态优先级将线程插入相同优先级的线程列表,以及如何调整线程位置。所有调度具有抢占性,较高优先级线程准备运行时会抢占当前线程,并返回到相同优先级的等待列表。

进程调度包括两个队列:进程初始进入ready队列等待调度,遇到I/O阻塞、子进程结束或软中断等会进入wait队列,阻塞解除后返回ready队列。

SCHED_FIFO:First in-first out调度策略适用于静态优先级大于0的线程,线程立即抢占所有运行的SCHED_OTHER、SCHED_BATCH或SCHED_IDLE线程。不使用时间片,SCHED_FIFO策略线程应遵守规则。

SCHED_RR:轮询调度策略增强SCHED_FIFO,每个线程允许在最大时间段内运行。运行超过该时间段的SCHED_RR线程会被放置在优先级列表末尾。被更高优先级线程抢占后恢复运行,将在未过期时间段内继续。

SCHED_DEADLINE:结合GEDF与CBS的调度策略,适用于短任务模型。每个任务有相对截止时间与计算时间,使用sched_setattr(2)设置Runtime、Deadline与Period。内核要求参数至少1024,小于2^63。

CBS确保任务间不干扰,当SCHED_DEADLINE线程不可运行时,内核阻止其运行,执行准入测试确保修改可行。总的CPU利用率应小于可用CPU。使用SCHED_DEADLINE策略的线程优先级最高,会抢占其他策略下的线程。

使用SCHED_DEADLINE策略的线程fork(2)返回EAGAIN错误,除非设置reset-on-fork标记。调用sched_yield(2)停止当前任务,等待新周期。

SCHED_OTHER:默认Linux分时调度策略,静态优先级为0(普通线程)。动态优先级基于nice值,决定选择运行的线程。

SCHED_BATCH:用于静态优先级为0的批量处理进程,调度类似SCHED_OTHER,考虑CPU密集型行为,避免交互引起的抢占。

SCHED_IDLE:用于非常低优先级任务,nice值不影响此策略。

设置子进程的调度策略可使用reset-on-fork标识,fork(2)后子进程会disable此标识。

在Linux 2.6.12前,只有拥有特权的线程可设置非0静态优先级。后续版本仅非特权线程在调用者有效用户ID与目标线程一致时设置SCHED_OTHER策略。

设置或修改SCHED_DEADLINE策略需特权线程,RLIMIT_RTPRIO定义非特权线程设置SCHED_RR与SCHED_FIFIO策略的静态优先级上限。

实时进程与SCHED_FIFO、SCHED_RR中无限循环处理可能阻塞其他线程。从Linux 2.6.25起,通过RLIMIT_RTTIME限制实时进程CPU使用上限。

从Linux 2.6.25起,为非实时进程保留CPU时间,shell可停止进程以释放资源。

子进程通过fork(2)继承调度策略与参数,使用execve(2)可保存策略与参数。

SCHED_FIFO、SCHED_RR或SCHED_DEADLINE策略下调度的非阻塞无限循环可能导致系统冻结。从Linux 2.6.25起,通过RLIMIT_RTTIME限制实时与deadline进程使用CPU。

autogroup特性从Linux 2.6.38起提供,提升多进程与CPU密集型负载的交互式桌面性能。设置CONFIG_SCHED_AUTOGROUP启用特性,通过文件/proc/sys/kernel/sched_autogroup_enabled控制。autogroup允许进程以组形式调度,提升CPU分配效率。

nice值影响调度,SCHED_FIFO、SCHED_RR与SCHED_DEADLINE策略下,nice值仅影响同一任务组内的线程调度。

autogroup与cgroups CPU控制器可分别设置进程占用的CPU,cgroup配置覆盖autogroup。

从Linux 2.6.18起,Linux逐渐具备实时功能,部分依赖realtime-preempt补丁集。在补丁合并主线前,实时性能需通过安装补丁实现。

在/proc/sched_debug查看CPU核心调度情况,如docker服务在core1上的调度;/proc/$pid/sched查看特定进程调度情况。

详细信息参考原文作者charlieroro的博客园文章。

linux进程调度的三种策略是什么

linux内核的三种主要调度策略:

1,SCHED_OTHER分时调度策略,

2,SCHED_FIFO实时调度策略,先到先服务

3,SCHED_RR实时调度策略,时间片轮转

实时进程将得到优先调用,实时进程根据实时优先级决定调度权值。分时进程则通过nice和counter值决定权值,nice越小,counter越大,被调度的概率越大,也就是曾经使用了cpu最少的进程将会得到优先调度。

SHCED_RR和SCHED_FIFO的不同:

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

SCHED_FIFO一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃。

如果有相同优先级的实时进程(根据优先级计算的调度权值是一样的)已经准备好,FIFO时必须等待该进程主动放弃后才可以运行这个优先级相同的任务。而RR可以让每个任务都执行一段时间。

相同点:

RR和FIFO都只用于实时任务。

创建时优先级大于0(1-99)。

按照可抢占优先级调度算法进行。

就绪态的实时任务立即抢占非实时任务。

所有任务都采用linux分时调度策略时:

1,创建任务指定采用分时调度策略,并指定优先级nice值(-20~19)。

2,将根据每个任务的nice值确定在cpu上的执行时间(counter)。

3,如果没有等待资源,则将该任务加入到就绪队列中。

4,调度程序遍历就绪队列中的任务,通过对每个任务动态优先级的计算权值(counter+20-nice)结果,选择计算结果最大的一个去运行,当这个时间片用完后(counter减至0)或者主动放弃cpu时,该任务将被放在就绪队列末尾(时间片用完)或等待队列(因等待资源而放弃cpu)中。

5,此时调度程序重复上面计算过程,转到第4步。

6,当调度程序发现所有就绪任务计算所得的权值都为不大于0时,重复第2步。

所有任务都采用FIFO时:

1,创建进程时指定采用FIFO,并设置实时优先级rt_priority(1-99)。

2,如果没有等待资源,则将该任务加入到就绪队列中。

3,调度程序遍历就绪队列,根据实时优先级计算调度权值(1000+rt_priority),选择权值最高的任务使用cpu,该FIFO任务将一直占有cpu直到有优先级更高的任务就绪(即使优先级相同也不行)或者主动放弃(等待资源)。

4,调度程序发现有优先级更高的任务到达(高优先级任务可能被中断或定时器任务唤醒,再或被当前运行的任务唤醒,等等),则调度程序立即在当前任务堆栈中保存当前cpu寄存器的所有数据,重新从高优先级任务的堆栈中加载寄存器数据到cpu,此时高优先级的任务开始运行。重复第3步。

5,如果当前任务因等待资源而主动放弃cpu使用权,则该任务将从就绪队列中删除,加入等待队列,此时重复第3步。

所有任务都采用RR调度策略时:

1,创建任务时指定调度参数为RR,并设置任务的实时优先级和nice值(nice值将会转换为该任务的时间片的长度)。

2,如果没有等待资源,则将该任务加入到就绪队列中。

3,调度程序遍历就绪队列,根据实时优先级计算调度权值(1000+rt_priority),选择权值最高的任务使用cpu。

4,如果就绪队列中的RR任务时间片为0,则会根据nice值设置该任务的时间片,同时将该任务放入就绪队列的末尾。重复步骤3。

5,当前任务由于等待资源而主动退出cpu,则其加入等待队列中。重复步骤3。

系统中既有分时调度,又有时间片轮转调度和先进先出调度:

1,RR调度和FIFO调度的进程属于实时进程,以分时调度的进程是非实时进程。

2,当实时进程准备就绪后,如果当前cpu正在运行非实时进程,则实时进程立即抢占非实时进程。

3,RR进程和FIFO进程都采用实时优先级做为调度的权值标准,RR是FIFO的一个延伸。FIFO时,如果两个进程的优先级一样,则这两个优先级一样的进程具体执行哪一个是由其在队列中的未知决定的,这样导致一些不公正性(优先级是一样的,为什么要让你一直运行?),如果将两个优先级一样的任务的调度策略都设为RR,则保证了这两个任务可以循环执行,保证了公平。

Ingo Molnar-实时补丁

为了能并入主流内核,Ingo Molnar的实时补丁也采用了非常灵活的策略,它支持四种抢占模式:

1.No Forced Preemption(Server),这种模式等同于没有使能抢占选项的标准内核,主要适用于科学计算等服务器环境。

2.Voluntary Kernel Preemption(Desktop),这种模式使能了自愿抢占,但仍然失效抢占内核选项,它通过增加抢占点缩减了抢占延迟,因此适用于一些需要较好的响应性的环境,如桌面环境,当然这种好的响应性是以牺牲一些吞吐率为代价的。

3.Preemptible Kernel(Low-Latency Desktop),这种模式既包含了自愿抢占,又使能了可抢占内核选项,因此有很好的响应延迟,实际上在一定程度上已经达到了软实时性。它主要适用于桌面和一些嵌入式系统,但是吞吐率比模式2更低。

4.Complete Preemption(Real-Time),这种模式使能了所有实时功能,因此完全能够满足软实时需求,它适用于延迟要求为100微秒或稍低的实时系统。

实现实时是以牺牲系统的吞吐率为代价的,因此实时性越好,系统吞吐率就越低。

Linux进程调度-应用内核设置调度策略和优先级

一、进程调度策略设置

1.函数使用说明

sched_setscheduler()为指定线程设置调度策略和相关参数。如果指定pid为零,则设置调用线程的调度策略和参数。参数param的解释取决于所选策略。当前Linux支持的策略包括:SCHED_OTHER(标准循环分时策略),SCHED_BATCH(批处理样式进程执行),SCHED_IDLE(运行低优先级后台作业)。同时,还支持实时策略,如SCHED_FIFO(先进先出策略)和SCHED_RR(循环策略)。

sched_getscheduler()查询线程的调度策略。如果pid为零,则检索调用线程的策略。需要root权限设置成功。

2. SCHED_FIFO先进先出调度

SCHED_FIFO只能在静态优先级高于0的情况下使用。当SCHED_FIFO线程变为可运行时,将立即抢占所有当前运行的 SCHED_OTHER,SCHED_BATCH或 SCHED_IDLE线程。此策略提供简单调度,无需时间分片。

3. SCHED_RR循环调度

SCHED_RR是 SCHED_FIFO的增强版,所有内容同样适用,但允许每个线程在最大时间范围内运行。如果 SCHED_RR线程运行时间达到或超过最大时间,将放在优先级列表的末尾。

4. SCHED_OTHER默认Linux分时调度

SCHED_OTHER策略适用于不需要实时机制的所有线程。根据动态优先级选择要运行的线程,优先级基于nice值。

5. SCHED_BATCH计划批处理

SCHED_BATCH仅用于静态优先级0。策略类似于 SCHED_OTHER,但假定线程占用大量CPU,减少调度损失。

6. SCHED_IDLE计划非常低优先级作业

SCHED_IDLE用于极低优先级作业,nice值对此策略无影响。

7.重置子进程调度策略

从Linux 2.6.32开始,可使用 sched_setscheduler()设置 SCHED_RESET_ON_FORK标志,防止子进程继承特权调度策略。

8.特权和资源限制

在2.6.12之前的Linux内核中,只有特权线程可以设置非零静态优先级。从Linux 2.6.12开始,非特权线程可更改调度策略和优先级,但需遵循资源限制。

9.响应时间

高优先级线程等待I/O时,有响应时间限制。设备驱动程序可使用“慢中断”减少此时间。

10.杂项

子进程继承调度策略,execve保留策略。实时进程需内存锁定避免分页延迟,使用mlock或mlockall完成。

11.返回值

sched_setscheduler()成功返回零, sched_getscheduler()返回策略值。错误情况包括参数无效、权限不足等。

12.进程设置使用例子

试验代码和运行结果展示设置策略和优先级对系统性能的影响。

13.线程调度策略设置

设置线程调度策略需root权限。

14.内核线程调度策略和优先级设置

参考内核文件进行设置。

15. chrt设置和查看进程调度策略和优先级

使用示例展示设置和查看方法。

16. renice设置普通进程优先级

调整进程优先级的示例和原理解释。

通过以上内容,您可以详细了解Linux进程调度策略、优先级设置及其实现,为优化系统性能提供依据。

阅读剩余
THE END