Linux进程调度内核实现分析

【Linux 内核源码分析】进程调度 -CFS 调度器 在CFS(Completely Fair Scheduler)调度器中,任务的权重值由其nice值决定,通过对比不同任务的权重值,CFS会分配合理的CPU时间片给每个任务。这种方式实现了一种类似于多态的效果,即不同的任务可以使用不同的调度算法,而调度器的函数指针则根据具体的调度器类型来指向对应的函数。通过这种方式,Linux 内核可以根据任务的调度器类型来调用相应的调度函数,实现了灵活的调度策略,并且能够方便地扩展和切换不同的调度器。高优先级的任务会获得更多的虚拟运行时间,在排序和选择调度时更容易被选中。 阅读详情

本文根据两篇博客总结,它们的地址分别是:
http://blog.youkuaiyun.com/giantpoplar/article/details/51791002
http://blog.youkuaiyun.com/giantpoplar/article/details/51791002
 

目录

所谓抢占

  • 抢占式
    • 调度程序决定进程何时停止,为其他进程腾出 CPU 资源,这种强制挂起行为就是抢占。进程被抢占前运行时间为提前设定好的时间片。
  • 非抢占
    • 进程占据 CPU 资源不放,除非自己主动调用 schedule() 函数,这称为进程让步。

什么是调度

调度的原因:现代操作系统都是多任务的,为了能让操作系统更好的发挥多任务的特性,需要一个管理程序来管理所有任务,这个程序就是调度程序。

调度程序的功能有:

  1. 负责让那些进程运行,那些进程等待
  2. 决定每个进程运行多长时间

此外为了更好地用户体验,运行中的进程还可以立即被其他更紧急的进程打断。

总之调度是一个平衡的过程。一方面,它要保证各个运行的的进程能够最大限度使用CPU(即尽量少的切换进程),另一方面,保证各个进程公平使用CPU(即防止一个进程长时间独占CPU的情况)

调度实现原理

调度主要基于进程优先级和时间片实现。

进程的优先级

进程的优先级有两种度量方法,一种是nice值,一种是实时优先级。
nice 值的范围是 -20~+19,值越大优先级越低,也就是说 nice 值为-20的进程优先级最大。
实时优先级的范围是 0~99,与 nice 值的定义相反,实时优先级是值越大优先级越高。
实时进程都是一些对响应时间要求比较高的进程,因此系统中有实时优先级高的进程处于队列的话,它们会抢占一般进程的运行时间。

进程的实时优先级高于 nice 值,在内核中,实时优先级的范围是 0~MAX_RT_PRIO-1。
MAX_RT_PRIO的定义参见 include/linux/sched.h

    #define MAX_USER_RT_PRIO    100
    #define MAX_RT_PRIO         MAX_USER_RT_PRIO

nice值在内核中的范围是 MAX_RT_PRIO~MAX_RT_PRIO+40 即 MAX_RT_PRIO~MAX_PRIO

    #define MAX_PRIO            (MAX_RT_PRIO + 40)

一个进程有只能拥有实时优先级和 nice 值其中之一。

时间片

有了优先级,就可以决定谁先运行了。但是对于调度程序来说,并不是运行一次就结束了,必须知道间隔多久进行下次调度。
于是就有了时间片的概念。时间片表示一个进程抢占前能持续运行的时间。
时间片设定,过大会让系统响应变慢;过小会产生由于进程频繁切换带来的开销。
默认的时间片一般为 10ms。

调度的实现原理

基本步骤我的理解是:

  1. 首先确定每个进程占用多少 CPU 时间,如利用 nice 值进行计算。
  2. 让占用 CPU 时间多的先运行。(让列宁同志先走)
  3. 运行完后,扣除运行进程的 CPU 时间,接下来继续重复这三步。

Linux上调度实现的方法

Linux 上采用了“完全公平调度算法”,简称“CFS”。
CFS 算法在分配给每个进程 CPU 时间时,不是分配给它们一个 CPU 的绝对时间,而是根据进程的优先级分配给它们一个占用 CPU 时间的百分比。

举例:

进程名nice值百分比
进程A110%
进程B330%
进程C660%

由上图可知,占据百分比之和就是 100%。所以我的理解是 Linux 下 CFS 算法的主要步骤有:

  1. 计算每个进程的 vruntime,通过 update_curr() 函数更新进程的 vruntime。
  2. 选择具有最小 vruntime 的进程投入运行。
  3. 进程运行完后,更新 vruntime,再回到步骤 2。

vruntime 变量存放进程的虚拟运行时间,该运行时间(花在运行上的时间和)是通过对可运行总数的加权后得出的,单位是 ns。计算权重实际上就是计算占用 CPU 的百分比,通过它得出 vruntime,用来记录一个程序运行了多长时间以及还应运行多久。

  • 时间记账
    使用 sched_entity 结构体进行记账,该结构体在 task_struct 中被包含。vruntime 作用上面说过了。
  • 进程选择
    使用红黑树存放进程队列,以 vruntime 为键值,每次选择 vruntime 最小的进程。这里有用到了一个 trick,使用 leftmost 缓存了红黑树的最左叶子节点,提高效率(STL也这么干了)。
  • 调度器入口
    schedule() 函数调用 pick_next_task() 函数,按照优先级从大到小一次检查每一个调度类,从最高优先级调度类中,选择最高优先级进程。
  • 睡眠和唤醒
    睡眠:进程标记为 TASK_INTERRUPTIBLE 或 TASK_UNINTERRUPTIBLE 状态,从红黑树中移除,放入等待队列,调用 schedule 选择和执行一个其他的进程。
    唤醒:通过 wake_up() 函数唤醒,进程标记为 TASK_RUNNING 状态,从等待队列放入红黑树中。

上下文切换

  • switch_mm() 函数把虚拟内存从上一个进程切换到新进程。
  • switch_to() 从上一个处理器状态切换到新处理器状态,保存回复栈寄存器信息。

调用schedule()的时机

  • 某个进程应该被抢占,scheduer_tick 设置为 need_resched。
  • 一个优先级高的进程进入可执行状态,try_wake_up 设置为 need_resched。
  • 从内核返回用户空间或从中断返回,内核检查 need_resched。如果已经设置,内核会在继续执行之前调用调度程序

抢占时机

用户抢占:

  1. 从系统调用返回用户空间。
  2. 从中断处理程序返回用户空间。

内核抢占:

  1. 中断处理程序正在执行,且返回内核空间之前。
  2. 内核代码再一次具备可抢占性的时候(我认为就是出于临界区之外时)。
  3. 如果内核中的代码显示调用 schedule()。
  4. 如果内核中任务阻塞。

实时调度

SCHED_FIFO:不使用时间片,先入先出。只有更高优先级别的SCHED_FIFO,SHED_RR 进程才能抢占,同一级别不能抢占。
SCHED_RR:带有时间片,实时轮流调度。时间片耗尽,允许同一级别进程抢占。

Linux内核实时机制26 - RT调度器9 - 运行时数据更新 update_curr_rt 实时进程所在的cpu占用超时,可以向其他的CPU借用,将其他CPU的时间借用过来,这样此实时进程所在的CPU占有率达到100%,这样做的目的是为了避免实时进程由于缺少CPU时间而向其他的CPU迁移,减少不必要的迁移成本。rt_rq实时进程运行队列里面提到rt_time和rt_runtime,一个是运行累计时间,一个是最大运行时间,当运行累计时间超过最大运行时间的时候,rt_throttled则被设置为1。5、如果累计运行时间大于最大运行时间, rt_b为运行队列rt_rq的进程组带宽控制结构体指针。 阅读详情

相关推荐

Win10安装Nek5000

1 安装wsl 2 2 安装Nek5000 3 安装依赖项 4 安装openmpi 5 配置Nek5000 6 编译Nek5000 7 运行Nek5000算例 8 安装paraview并查看结果

weixin_43176703的博客 3451

【读书笔记】Linux内核设计与实现-进程调度

文章目录1.多任务--抢占、时间片和让步2.Linux的进程调度--O(1)调度程序3.策略--决定调度程序在何时让什么进程运行3.1 I/O消耗型和处理器消耗型的进程3.2 进程优先级3.3 时间片3.4 调度策略的活动--建议阅读原书此小节,很形象的说明了“策略”4.Linux调度算法4.1 调度器类4.2 Unix系统中的进程调度4.3 公平调度5.Linux调度的实现5.1 时间记账5.2...

wang 恒 的博客 788

手把手教你为智能手表DIY一个离线导航:LVGL + SD卡地图实战

本文详细介绍了如何为智能手表DIY一个离线导航系统,结合LVGL图形库和SD卡地图数据。从硬件选型、地图数据处理到LVGL地图引擎实现,提供了完整的实战指南,特别适合户外运动爱好者和嵌入式开发者。文章还分享了功耗优化、性能提升等实用技巧,帮助读者打造高效的离线导航解决方案。

weixin_42570484的博客 206

Linux内核中的进程调度-调度器基础

本文全面探讨了Linux内核的调度器机制,首先从基础概念入手,阐述了调度器在操作系统中扮演的角色——负责管理和协调系统中各个进程对CPU资源的访问,确保系统整体性能和响应能力。文章深入解析了Linux内核对调度器的具体实现。

qq_45652092的博客 2854

VLP16:使用pointcloud_to_laserscan将三维点云转化为二维LaserScan

velodyne16线激光雷达 VLP16:使用pointcloud_to_laserscan将三维点云转化为二维LaserScan

NEUer_ljx的博客 4619

IAR调试CC1310的错误:Fatal error:Failed to connect to the XDS emlulator (Error -241 @ 0x0:)

从simplelink_cc13x0_sdk_2_10_00_36导入collector工程后,rebuild后进行debug,出现了如图错误:Fatal error:Failed to connect to the XDS emlulator (connect ICEPick)...(Error -241 @ 0x0)A router subpath could not be accessed....

qq_40417648的博客 6228

linux进程的调度

进程状态 进程主要有7种状态:就绪状态、运行状态、轻度睡眠、中度睡眠、深度睡眠、僵尸状态、死亡状态。它们之间状态变迁如下: 进程描述符task_struct结构体中有个成员state专门用来描述进程的状态。 就绪状态:state为TASK_RUNNING,正在运行队列中等待调度器调度。 运行状态:state为TASK_RUNNING,被调度器命中,正在处理器中运行。 轻度睡眠:称为可打断的睡眠状态。state为TASK_INTERRUPTIBLE,可以被信号打断。 中度睡眠:state为TASK_KIL

m0_65931372的博客 6408

【数字图像处理第四版课后习题答案】第2章 数字图像基础(含英文原版)

如图 P2.3 所示,视网膜图像中与点相对应的直径 x 是由类似的三角形得到的。即得出 x = 0.085d。根据第 2.1 节中的讨论,并结合一些自由解释,我们可以将眼窝视为一个方形传感器阵列,拥有大约 337,000 个元素,这相当于一个大约 580×580 个元素的阵列。假设元素间距相等,则在 1.5 毫米长的直线上有 580 个元素和 579 个空间,共计 1,159 个。换句话说,如果一个点的直径 d<1.3×10-6 m,或者 d<15.3×10 m,眼睛就无法检测到这个点。

weixin_56463218的博客 1万+

OS----进程调度及实现(C语言)

进程调度四种算法源代码运行结果总结 四种算法 先来先服务算法 先来先服务调度算法是按照作业到达的先后次序进行调度,或者说是有优先考虑在系统中等待时间最长的作业,而不管该作业所需执行时间的长短,从后背作业队列中选择几个最先进入系统的作业,将他们调入内存,为它们分配资源和创建进程,然后将它放入就绪队列。每次进程调度就从酒席队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行,该进程一直运行到完成或发生某事件而阻塞后,进程调度程序才将处理及分配给其他进程。 短作业优先算法 短作业优先调度算法是以作业

m0_50527451的博客 1135

【机器学习与数据挖掘实战 | 医疗】案例18:基于Apriori算法的中医证型关联规则分析

本案例针对三阴乳腺癌患者,经问卷调查收集数据并筛选处理形成原数据,经清洗、特征选择与变换后,构建Apriori模型,基于业务理解与建模结果,分析患者症状与中医证型关联,并据症状给出建议 。

Morse_Chen的博客 1380

电脑技巧:Hyper-V安装UOS操作系统图文教程

今天给大家分享微软官方Hyper-v虚拟机管理软件安装UOS操作系统图文教程,感兴趣的朋友也可以下载试一试,当然有啥问题也可以互相沟通交流!

IT技术分享社区 4707

Linux中进程调度的触发场景以及对应的内核源码总结

Linux 进程调度的触发场景可分为主动触发(进程主动放弃 CPU)和被动触发(内核强制抢占或强制调度)两类,不同场景景对应不同的内核源码实现。一、主动触发调度(进程自愿放弃 CPU)进程通过主动调用调度相关函数释放 CPU,常见于阻塞、休眠或完成任务时。1. 进程阻塞(等待资源)场景:进程等待 I/O(如磁盘读写、网络数据)、信号量、锁等资源时,会主动进入休眠状态并触发调度。核心函数schedule()(最核心的调度入口)源码位置调用链示例以等待信号量为例:down(&sem)→。

qq_28576837的博客 1390

边缘AI工业落地:YOLO26-Seg + RK3588 NPU 极致部署(低功耗+实时实例分割,工业场景全覆盖)

本次实战汇总了「YOLO26-Seg+RK3588 NPU」工业边缘部署中最常见、最致命的8个坑点,所有坑点均来自真实工业项目,解决方案均为零代码/一键操作,无需复杂配置,能让你少走90%的弯路,节省大量时间,必看必记!❌ RKNN转换报错「算子不支持/模型加载失败」→ ✅ 导出ONNX时必须指定opset=12,重新导出即可,RK3588唯一兼容版本;❌ 分割mask错位/轮廓模糊 → ✅ 导出ONNX时加,并保证RKNN的归一化参数与YOLO26一致,零代码修复;

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1718

Linux内核调度分析(进程调度)

在每个进程的平均运行时间大于最小粒度的情况下,CFS无疑是公平的,nice值用于计算一个进程在当前这个最小调度周期中所应获得的处理器时间占比,这样就算nice值不同,只要差值相同,总是能得到相同的时间片。,再简单一点,它是一种以树节点方式储存数据的结构,每个节点对应了一个键值,利用这个键值可以快速索引树上的数据,并且它可以按照一定的规则自动调整每个节点的位置,使得通过键值检索到对应节点的速度和整个树节点的规模呈指数比关系。这样,进程所获得的实际CPU时间就和系统的负载密切相关。

m0_74282605的博客 496

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

linux系统中进程调度所采用的策略,Linux系统中进程调度策略

2009年第5期商丘职业技术学院学报Vol.8,No.5    第8卷(总第44期)JOURNALOFSHANGQIUVOCATIONALANDTECHNICALCOLLEGEOct.,2009文章编号:1671-8127(2009)05-0042-03Linux系统中进程调度策略葛 君1,2,郑凤婷2(1.软件工程国家重点实验室(武汉大学),湖北武汉,430072;2.商丘职业技术学院,河南商丘...

weixin_39580748的博客 1018

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Linux内核分析之理解进程调度时机跟踪分析进程调度与进程切换的过程

一、原理分析 1.调度时机 背景不同类型的进程有不同的调度需求第一种分类I/O-bond:频繁的进行I/O;通常会花费很多时间等待I/O操作的完成CPU-bound:计算密集型;需要大量的CPU时间进行运算 第二种分批处理进程(batch process):不必与用户交互,通常在后台运行;不必很快响应。典型的批处理程序:编译程序、科学计算实时进程(real-time process):...

diedun6115的博客 332

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Linux内核进程调度以及定时器实现机制(转)

摘要】本文简单介绍了任务的各种状态和PCB的结构,分析了几种任务调度策略,详解了schedule,并分析了如何进行进程上下文切换;随后分析了2.6内核如何优化了任务调度算法;最后介绍了内核定时器的实现机制和系统调用的实现过程。【关键词】进程控制块PCB,RR,FIFO,内核调度算法,任务切换,内核定时,timer,软中断softirq,系统调用  一、2.6版以前内核进程调度机制简

ctwei85的专栏 1696

Linux的进程调度及内核实现

Linux进程调度机制分析:本文详细解析了Linux内核的进程调度实现,包括关键数据结构(task_struct、sched_class)、调度策略(CFS公平调度、RT实时调度)及触发机制。CFS采用红黑树管理进程,通过vruntime实现公平分配;RT调度器则通过优先级队列处理实时任务。调度过程分为主动/被动触发,最终通过schedule()完成上下文切换。文章还涉及进程状态转换、优先级规则及调度器核心算法的实现细节。

asbcddasds的博客 797

linux内核分析(linux中的调度)

在 Linux 中,调度器负责管理系统中的进程和线程的执行顺序,以确保 CPU 资源的有效利用。任务调度:决定哪个进程或线程在任何时刻获得 CPU 使用权。时间片分配:为每个任务分配执行时间,确保公平性和响应性。优先级处理:根据任务的优先级和其他调度策略,安排任务执行顺序。上下文切换:保存当前任务的状态,加载下一个任务的状态,以实现任务切换。调度器通过不同的调度策略(如完全公平调度器 CFS、实时调度策略等)来优化系统性能、响应时间和任务的公平性。实时任务优先级和。

m0_49476241的博客 2133

Linux内核中进程调度的实现机制

Linux内核进程调度机制通过模块化调度类CFS调度类:基于vruntime和红黑树,为普通进程提供公平的CPU分配,动态调整时间片。实时调度类:通过SCHED_FIFO和SCHED_RR策略,确保实时任务的低延迟响应。多CPU负载均衡:动态迁移进程,避免单CPU过载。高效上下文切换:通过硬件优化(如TLB ASID)减少切换开销。这种设计既满足了普通应用的公平性需求,又支持实时任务的严格时间约束,是Linux作为通用操作系统的核心竞争力之一。

u010632343的博客 1083

庖丁解牛_ Linux进程的调度与切换

Linux操作系统分析 课程心得体会

qq_63859460的博客 1146

进程调度

在Linux系统中,进程是可被调度的实体。虽然当线程被发明出来之后,进程更多的是被当做资源的实体,而线程作为可被调度的执行单元被操作系统调度,但是,Linux因为历史等原因,使得它调度的实体仍然是进程。进程之间因为可以“并发”,所以他们之间的同步要通过某种方式的通信实现,这也就是

zhang_shuai_2011的专栏 795

转载 linux2.6内核进程调度

linux2.6内核进程调度  Linux2.4内核进程调度的缺陷:    Linux2.4 内核的进程调度采用时间片轮转和优先级相结合的调度策略,但存在以下几个致命缺陷:    1>调度算法时间复杂度是 O(n)。2.4 内核每次调度都要进行一次循环,耗时与当前就绪进程数有关,因此达不到实时性的要求;时间片重算时必须给 task

abo8888882006的专栏 1357

Linux进程调度与切换

在多进程的操作系统中,进程调度是一个全局性、关键性的问题,它对系统的总体设计、 系统的的实现、功能设置以及各个方面的性能都有着决定性的影响。根据调度的结果所作的进程切换的速度,也是衡量一个操作系统性能的重要指标。进程调度算法的设计,还对系统的复杂性有着极大的影响,常常会由于实现的复杂程度而在功能与性能方面作出必要的权衡和让步。进程调度与时间的关系非常密切,因此,本章首先讨论与时间相关的主题,然后才讨论进程的调度,最后介绍了 Linux 中进程是如何进行切换的。

qq_28576837的博客 1007
上一篇: Linux进程管理、进程创建、线程实现、僵尸进程
下一篇: Linux中断机制分析
FreeeLinux
博客等级 码龄11年 421粉丝 356原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值