前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊Linux内核进程调度下篇

聊聊Linux内核进程调度下篇

作者头像
用户4700054
发布2022-08-17 13:15:42
1.2K0
发布2022-08-17 13:15:42
举报
文章被收录于专栏:存储内核技术交流

进程优先级

  • Linux内核中进程优先级一般分为动态优先级和静态优先级,动态优先级是内核根据进程的nice值、IO密集行为或者计算密集行为以及等待时间等因素,设置给普通的进程;静态优先级是用户态应用设置给实时进程。在调度中静态优先级的进程优先级更高。
  • 一般应用分为IO密集型和计算密集型;I/O密集型是进程执行I/O操作时候等待资源或者事件时候,数据读取到后恢复进程的运行,这样基本出于等待IO和运行之间进行交替,由于具有这样的特性,进程调度器通常会将短的CPU时间片分配给I/O密集型进程。计算密集型是进程保持在CPU时间片上,需要最大限度的利用处理器的计算能力。任何普通进程的nice值在-20~19之间,0是默认,较高的nice值表示较低的进程优先级;实时进程的优先级范围是在0~99
  • 从内核的优先级角度,所有的进程都处于0~139,其中的0~99是分配实时进程;100~139是分配普通进程,代表的nice值为-20~19.

实际调度器

调度器通用元素
CFS(完全公平)调度器
  • Linux内核中所有动态优先级的进程都是有CFS调度器处理,通常Linux内核中大部分都是非实时进程,所以CFS进程调度器也是最繁忙的调度器。CFS调度器不依赖于传统的时间片来分配CPU的时间,而是通过虚拟时间,这个虚拟时间是进程获取CPU时间的时间单位。CFS调度器根据虚拟时间值,CFS决定进程的最终运行时间,同时也会涉及使用nice来衡量一个进程和其他进程的竞争关系。
  • 优先级是根据进程等待时间、进程运行时间、进程的历史行为、进程的nice值等因素动态设置。在计算进程优先级的时候,CFS不仅依赖于进程的nice值,同时还要考虑进程的负载,内核中维护了进程的负载权重数组(prio_to_weight),每个nice值对应一个负载权重;对于进程来说,nice值减一,CPU时间片就会减少10%;nice值加一,CPU时间片会增加10%。
  • CFS调度器采用了红黑树来作为运行队列,红黑树保存了所有的竞争进程,根据红黑树的特性,执行插入和搜索效率非常高。高优先级的进程在树的最左边节点,通过pick_next_task()从红黑树中选择最左边的节点来进行调度。
代码语言:javascript
复制
// CFS完全公平调度器
const struct sched_class fair_sched_class = {
	.next			= &idle_sched_class,
	.enqueue_task		= enqueue_task_fair,
	.dequeue_task		= dequeue_task_fair,
	.yield_task		= yield_task_fair,
	.yield_to_task		= yield_to_task_fair,

	.check_preempt_curr	= check_preempt_wakeup,

	.pick_next_task		= pick_next_task_fair,
	.put_prev_task		= put_prev_task_fair,

#ifdef CONFIG_SMP
	.select_task_rq		= select_task_rq_fair,
	.migrate_task_rq	= migrate_task_rq_fair,

	.rq_online		= rq_online_fair,
	.rq_offline		= rq_offline_fair,

	.task_dead		= task_dead_fair,
	.set_cpus_allowed	= set_cpus_allowed_common,
#endif

	.set_curr_task          = set_curr_task_fair,
	.task_tick		= task_tick_fair,
	.task_fork		= task_fork_fair,

	.prio_changed		= prio_changed_fair,
	.switched_from		= switched_from_fair,
	.switched_to		= switched_to_fair,

	.get_rr_interval	= get_rr_interval_fair,

	.update_curr		= update_curr_fair,

#ifdef CONFIG_FAIR_GROUP_SCHED
	.task_change_group	= task_change_group_fair,
#endif
};
实时调度器
  • Linux内核中支持实时进程,它们是由实时调度器来进行调度。rt进程被分配了静态优先级,并且在内核中保持不变。于CFS不同,实时调度器采用了每个优先级1~99的单链表,并非采红黑树作为运行队列。实时调度器采用了fiforr调度策略.
  • fifo调度策略采用先进先出的方法来调度实时进程。在该策略下进程是没有任何时间片下运行的,一直在运行。当调度器遇到优先级更高的可执行的fiforrdeadline任务时候,fifo进程会被抢占;
  • rr调度策略是采用轮询的方法来调度实时进程,这个策略和fifo类型类似,不同的是rr调度策略是给进程分配了时间片来运行。进程的时间片过期后,进程会被添加到链表的尾部,具有相同优先级的进程会以轮询的方式运行,直到高优先级进程抢占。
代码语言:javascript
复制
// fifo和rt的实时进程调度器
const struct sched_class rt_sched_class = {
	.next			= &fair_sched_class,
	.enqueue_task		= enqueue_task_rt,
	.dequeue_task		= dequeue_task_rt,
	.yield_task		= yield_task_rt,

	.check_preempt_curr	= check_preempt_curr_rt,

	.pick_next_task		= pick_next_task_rt,
	.put_prev_task		= put_prev_task_rt,

#ifdef CONFIG_SMP
	.select_task_rq		= select_task_rq_rt,

	.set_cpus_allowed       = set_cpus_allowed_common,
	.rq_online              = rq_online_rt,
	.rq_offline             = rq_offline_rt,
	.task_woken		= task_woken_rt,
	.switched_from		= switched_from_rt,
#endif

	.set_curr_task          = set_curr_task_rt,
	.task_tick		= task_tick_rt,

	.get_rr_interval	= get_rr_interval_rt,

	.prio_changed		= prio_changed_rt,
	.switched_to		= switched_to_rt,

	.update_curr		= update_curr_rt,
};
  • deadline调度策略,在Linux内核的3.14开始引入了,deadline调度器基于全局最早的截止期优先和固定带宽服务器算法,于预先确定其运行时的需求。一个进程内运行多个任务,每个任务都会有一个截止期(在截止期内必须完成执行)和一个计算时间,该时间定义ICPU完成进程执行所需要的时间。
代码语言:javascript
复制
// 实时进程的新的调度器deadline
const struct sched_class dl_sched_class = {
	.next			= &rt_sched_class,
	.enqueue_task		= enqueue_task_dl,
	.dequeue_task		= dequeue_task_dl,
	.yield_task		= yield_task_dl,

	.check_preempt_curr	= check_preempt_curr_dl,

	.pick_next_task		= pick_next_task_dl,
	.put_prev_task		= put_prev_task_dl,

#ifdef CONFIG_SMP
	.select_task_rq		= select_task_rq_dl,
	.migrate_task_rq	= migrate_task_rq_dl,
	.set_cpus_allowed       = set_cpus_allowed_dl,
	.rq_online              = rq_online_dl,
	.rq_offline             = rq_offline_dl,
	.task_woken		= task_woken_dl,
#endif

	.set_curr_task		= set_curr_task_dl,
	.task_tick		= task_tick_dl,
	.task_fork              = task_fork_dl,

	.prio_changed           = prio_changed_dl,
	.switched_from		= switched_from_dl,
	.switched_to		= switched_to_dl,

	.update_curr		= update_curr_dl,
};
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 存储内核技术交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 进程优先级
  • 实际调度器
    • 调度器通用元素
      • CFS(完全公平)调度器
        • 实时调度器
        相关产品与服务
        文件存储
        文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档