
Linux 进程调度task_struct 与 sched_entity 如何协作分配 CPU5 分钟快速全解【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux电脑同时跑着视频渲染和浏览器渲染满负荷运转浏览器却照样丝滑滚动。这不是魔法而是 Linux 进程调度在背后不断给每个进程发牌。核心就两个结构体task_struct记下进程是谁、在干嘛sched_entity记下它欠调度器多少 CPU 时间。看懂这两个成员如何分工你对 Linux 进程调度的理解就通了大半。一、task_struct每个进程的身份证内核里每个进程线程都对应一个task_struct结构体相当于进程的完整档案身份、状态、栈、优先级全在这里。定义在 include/linux/sched.h。挑几个最实用的字段成员用途定义位置__state进程状态可运行 / 两种睡眠include/linux/sched.hpid/tgid进程编号你ps看到的就是它include/linux/sched.hprio调度优先级include/linux/sched/prio.hcomm进程名最长 15 个字符include/linux/sched.hse/rt/dl三类调度实体CFS 公平类、实时类、截止期限类include/linux/sched.h__state决定进程能不能上 CPU常见的三种取值TASK_RUNNING0就绪或正在跑TASK_INTERRUPTIBLE1可被信号打断的睡眠TASK_UNINTERRUPTIBLE2关键 I/O 期间的睡眠信号叫不醒状态之间是这样流转的注意睡下去的进程不在调度队列里唤醒瞬间才重新排队。调度器只对就绪的进程做决定所以状态字段是进入下一张账本的前置条件。二、sched_entity账本上决定先后的两个数字如果说task_struct是档案sched_entity即表里的se成员就是调度器真正翻看的账本。CFS 调度器把当前 CPU 上所有就绪进程组织成一颗红黑树按vruntime排序——vruntime 叫虚拟运行时间真实跑 1 秒按进程权重换算成多少虚拟时间就记多少。权重越大的进程单位真实时间 vruntime 涨得越慢自然越常出现在树的最浅位置也就拿更多 CPU。账本上最关键的三个字段struct sched_entity { struct load_weight load; /* 权重nice 值换算而来 */ u64 vruntime; /* 虚拟运行时间树里的排序键 */ u64 sum_exec_runtime; /* 累计真实运行时间 */ };权重来自 nice 值nice 0对应权重 1024nice 19跌到个位数附近nice -20则高出数万。所以给渲染进程调低 nice它的 vruntime 增长更慢浏览器就能持续抢到先手——公平不是人人等量而是按权重折算后的等量。三、一次 CPU 交接的四步报名、打分、中选、交接把 CFS 的一次调度看成一场比赛环节发生了什么相关函数 / 代码① 报名进程唤醒或新建sched_entity挂进本 CPU 的 cfs_rq 红黑树enqueue_entity()② 打分当前进程每跑一段vruntime 按权重折算递增账实时更新update_curr()③ 中选从树里取 vruntime 最小的一棵叶子进程pick_next_task_fair()④ 交接保存现场、切栈、换页表新进程接管 CPUcontext_switch()四步周而复始间隔由内核参数控制。④ 是最贵的一步要迁移 TLB、缓存上下文内核会用sched_migration_cost之类的阈值尽量让进程留在原 CPU 上续跑避免频繁搬迁——这就是你观察进程时看到迁移次数远低于切换次数的原因。四、实操3 条命令查看进程调度信息不用改内核/proc就能把账本翻出来。假设渲染进程 PID 是 12345cat /proc/12345/sched重点看se.vruntime和se.sum_exec_runtime前者是它虚拟时间上的欠款后者是真实跑过的毫秒数两者对照能看出权重把它的运行时间放大或压缩了多少。cat /proc/schedstat | head -4重点看每行的nr_switches自愿切换与nr_involuntary_switches被抢切换自愿远大于非自愿说明该核上的进程大多在等 I/O反之说明一直在被抢占系统偏忙。sysctl kernel.sched_base_slice_ns重点看 base slice 值当前内核基准时间片参数它是每次打分记账的粒度值越大单次运行越久、切换越省但对轻交互任务的响应变钝。想调优前先读它当前值再结合上面两条命令的现场数据做决定。五、延伸路径与实际价值源码与文档按顺序啃include/linux/sched.htask_struct与sched_entity的完整定义所有字段的第一手资料kernel/sched/fair.cCFS 调度器原理主战场enqueue_entity、pick_next_task_fair都在这Documentation/scheduler/sched-design-CFS.rstCFS 设计文档同目录还有 Documentation/scheduler/sched-eevdf.rst对运维线上卡顿先翻se.vruntime变化与/proc/schedstat多数疑似调度饿死都能定位到具体进程和核而不是盲调参数。 对开发者线程密集型程序多一个线程就少分一份权重用 nice 和线程数给关键路径让路往往比堆核数更有效。 展望主线已引入的 EEVDF 调度器把最小 vruntime升级为最早可运行期限短任务与长任务各得其所公平的定义正在被重新书写。从身份证到账本Linux 的调度逻辑其实一条线状态字段决定谁有资格上桌vruntime 决定谁先吃时间片参数决定每口多大。把这条线串起来进程调度就不再是玄学而是一套可观察、可推理、可调优的机制。【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考