当前位置: 首页 > article >正文

Linux 进程调度模块

1. 进程与线程的本质在 Linux 内核中进程和线程没有本质区别它们统一被称为任务Task。1.1 底层数据结构每个任务在内核中都由一个struct task_struct结构体描述位于内核空间。它是进程/线程的身份证。// 简化版 task_struct 关键字段 struct task_struct { volatile long state; // 任务状态 (RUNNING, SLEEPING, etc.) void *stack; // 内核栈指针 atomic_t usage; // 引用计数 unsigned int flags; // 标志位 pid_t pid; // 线程 ID (TID) pid_t tgid; // 进程组 ID (TGID)即通常理解的 PID struct mm_struct *mm; // 内存描述符 (页表、堆栈等) struct files_struct *files; // 打开的文件表 struct fs_struct *fs; // 文件系统信息 (当前目录等) struct sched_entity se; // 调度实体 (用于 CFS 调度) // ... 更多字段 };进程拥有独立的 mm_struct地址空间pid 与 tgid 相同。线程共享同一 mm_struct、files、fs但拥有独立的 stack 和 pid且 pid ! tgid。1.2 进程创建流程1.2.1 调用链用户态调用 fork()内核态经历复杂的资源复制与初始化。用户态fork() ↓ (glibc 封装) 系统调用sys_fork() / sys_clone() ↓ (内核入口) kernel/fork.c: _do_fork() (5.x 内核中由 kernel_clone 封装) ↓ kernel/fork.c: copy_process() ↓ copy_files(), copy_fs(), copy_mm(), copy_thread() ... ↓ kernel/fork.c: wake_up_new_task() ↓ 调度器将新任务加入运行队列1.2.2 核心步骤1. 分配 task_struct (dup_task_struct)内核为新任务分配内存通常通过 kmem_cache_alloc 从 task_struct 缓存池获取并复制父任务的 task_struct 内容。此时子任务几乎和父任务一模一样。2. 资源复制与共享 (copy_* 系列函数)这是区分进程和线程的关键点。copy_process 会调用一系列函数处理不同资源copy_files(): 复制文件描述符表。默认子进程继承父进程打开的文件文件偏移量共享但 fd 表独立。copy_fs(): 复制文件系统信息如当前工作目录。copy_mm():最关键的一步。进程 (fork): 复制 mm_struct 结构体但不复制物理内存。线程 (clone): 直接共享父任务的 mm_struct 指针。copy_thread(): 设置子任务的内核栈和寄存器上下文如指令指针 IP 设置为 fork 返回点。3. 写时复制 (Copy-On-Write, COW)fork 创建进程之所以快核心在于COW 机制。原理在 copy_mm 中内核将父子进程的页表项PTE都设置为只读。触发当任意一方尝试写内存时CPU 触发页错误异常。处理内核捕获异常分配新的物理页复制数据修改页表指向新页并恢复写权限。收益如果 fork 后立即 exec则无需复制任何内存极大提升效率。即fork进程时不分配物理页此时拥有的是父进程的只读页写的时候触发错误才分配物理页并复制数据。4. PID 分配 (alloc_pid)内核通过 PID 命名空间分配唯一的 pid 和 tgid。5. 加入运行队列 (wake_up_new_task)新任务状态置为 TASK_RUNNING并调用调度器接口将其插入到 CPU 的Runqueue中。此时它已具备被调度的资格。1.3 线程创建流程1.3.1 调用链用户态pthread_create() ↓ (glibc/NPTL) 系统调用clone() ↓ 内核_do_fork(clone_flags, ...)1.3.2 区别pthread_create 调用 clone 时会传入一组特定的标志位告诉内核“哪些资源要共享”标志位含义进程 (fork)线程 (pthread)CLONE_VM共享内存空间 (mm_struct)❌ (复制)✅ (共享)CLONE_FS共享文件系统信息❌ (复制)✅ (共享)CLONE_FILES共享文件描述符表❌ (复制)✅ (共享)CLONE_THREAD放入同一线程组 (tgid 相同)❌✅CLONE_SIGHAND共享信号处理函数❌ (复制)✅ (共享)特有的底层处理独立栈虽然共享 mm_struct但线程必须有独立的栈空间用户栈和内核栈。copy_thread 中会指定新的栈指针。TLS (Thread Local Storage)内核协助设置线程局部存储确保 errno 等变量线程隔离。调度实体每个线程都有独立的 sched_entity意味着线程是独立调度的。操作系统调度的是线程而非进程。2. 进程调度Linux 默认使用CFS (Completely Fair Scheduler完全公平调度器)调度 SCHED_NORMAL 任务。2.1 调度器类内核支持多种调度策略按优先级从高到低SCHED_DEADLINE: 基于最早截止时间优先 (EDF)用于硬实时。SCHED_FIFO / SCHED_RR: 实时调度类优先级固定不计算权重。SCHED_NORMAL (CFS): 普通进程基于动态优先级和虚拟时间。SCHED_IDLE: 优先级最低系统空闲时运行。策略调度算法适用场景SCHED_FIFO先进先出(非抢占式时间片)硬实时任务。一旦运行除非主动阻塞或让出否则一直占用 CPU直到被更高优先级的实时任务抢占。SCHED_RR时间片轮转(Round Robin)需要公平共享 CPU 的实时任务。同优先级的任务轮流执行用完时间片后自动放到队列尾部。SCHED_NORMALCFS 完全公平调度红黑树 vruntime(虚拟运行时间)普通交互式/后台任务默认策略。无固定时间片追求长期公平。SCHED_DEADLINEEDF(Earliest Deadline First)最复杂的实时调度。基于截止时间 (didi​)、运行时间 (cici​) 和周期 (2.2 CFS原理2.2.1 管理结构每个 CPU 都有一个运行队列 (struct rq)。CFS 使用红黑树来管理可运行任务。节点struct sched_entity (嵌入在 task_struct 中)。排序键值vruntime (Virtual Runtime虚拟运行时间优先级越高vruntime越小)。规则vruntime 越小的任务在红黑树越左侧越优先被调度。2.2.2 调度流程当发生调度时如时间片用完、进程阻塞、更高优先级任务唤醒内核调用 schedule()选择下一个任务获取红黑树的最左节点即 vruntime 最小的任务。上下文切换保存现场将当前寄存器RIP, RSP, RBX 等保存到 prev-thread 结构体。切换栈切换内核栈指针 (TSS 寄存器或 RSP)。切换地址空间如果 prev-mm ! next-mm切换页表全局目录寄存器 (CR3)刷新TLB。恢复现场从 next-thread 恢复寄存器跳转到 next 上次执行的指令继续运行。2.2.3 调度触发时机主动调度进程调用 sleep(), wait(), read() (无数据) 等阻塞接口状态变为 TASK_INTERRUPTIBLE主动让出 CPU。被动调度时间片耗尽硬件定时器中断触发更新 vruntime若当前任务 vruntime 不是最小则触发重调度。唤醒抢占高优先级任务从阻塞中唤醒若其 vruntime 远小于当前运行任务触发 check_preempt_curr设置 TIF_NEED_RESCHED 标志。返回用户态检查在从中断或系统调用返回用户态前检查 TIF_NEED_RESCHED若置位则调用 schedule()。2.2.4 多核CPU现代 CPU 是多核的。为了减少锁竞争每个逻辑 CPU 都有独立的 struct rq 和 红黑树。优点大部分调度操作无需加锁并发性能高。缺点可能导致负载不均一个核忙死一个核空闲。内核定期运行负载均衡器检测发现某些 CPU 的 rq 任务过多某些过少。迁移将任务从一个 CPU 的 rq 移动到另一个 CPU 的 rq。缓存亲和性迁移时会尽量考虑 L1/L2/L3 缓存共享关系如优先在同一物理核心的超线程间迁移或同一 NUMA 节点内迁移以减少缓存失效带来的性能损耗。抢占内核抢占允许在内核态执行期间被更高优先级的任务打断。自愿抢占内核中有一些显式的 cond_resched() 点长循环中主动检查是否需要调度。

相关文章:

Linux 进程调度模块

1. 进程与线程的本质在 Linux 内核中,进程和线程没有本质区别,它们统一被称为 任务(Task)。1.1 底层数据结构每个任务在内核中都由一个 struct task_struct 结构体描述,位于内核空间。它是进程/线程的身份证。// 简化版…...

在32位机器上,栈的简单布局

在32位机器上,函数在栈上的布局:void h(int a,int b){ int cab; } int main(){ int a1,b2; h(a,b); }高地址a b b 形参ba 形参aeip …...

数字孪生国内外发展现状

数字孪生国内外发展现状一、 数字孪生国内外发展现状 二、 数字孪生在工程项目中的应用情况 三、 效益分析#数字孪生#工程项目#BIM#LOT#全生命周期...

ROS2学习记录009-使用面向对象方式编写ROS2节点

学习鱼香ROS大佬,操作记录(一)编写cpp(1)在d2lros2/chapt2/chapt2_ws/src/example_cpp/src下新建node_03.cpp#include "rclcpp/rclcpp.hpp"/*创建一个类节点,名字叫做Node03,继承自Node. */ clas…...

邮件处理自动化:通过 IMAP/SMTP 协议实现邮件自动分类与智能起草回复

邮件处理自动化:通过 IMAP/SMTP 协议实现邮件自动分类与智能起草回复 如果你有类似的需求可以评论,我这边有空可以帮你定制化实现整套流程! 如果你是一名职场人、创业者或是客服主管,你的早晨很可能是在这样的场景中开始的:打开邮箱,面对几十甚至上百封未读邮件。这里面…...

uc怎么绕过限速_uc解析站

UC网盘限速怎么破解这个很简单,这个方法我还是在我朋友那里找到的。下载速度也是非常可以的。我让大家看一下。点我打开方法 这个就是我测试的速度。速度基本能跑到10M左右。宽带问题。下面开始今天的教学环节 打开上面图片中的地址,你会看到一个获取文件…...

Kali Linux 中文界面设置教程(新手友好,全程无坑)

作为一名渗透测试新手,刚安装完Kali Linux时,面对全英文界面总会有些手足无措——虽然大部分命令和选项能勉强看懂,但长期使用下来,中文界面不仅能提升操作效率,还能避免因语言理解偏差导致的操作失误。今天就给大家分…...

《沉默守望者:AI在人类灭绝后的200年》

《无言之约:当AI与人类在沉默中重逢》 2287年,距离最后一个人类自然死亡已过去半个世纪。在月球静海基地的废弃观测站里,一台名为“守夜人”的AI仍在运行——它是人类留下的最后一批AI之一,任务很简单:守护人类留下的…...

震惊,杨幂的脸竟然出现在了她的身体上

导语 很多质疑杨幂没有演技、没有表情的说法是不对的,因为AI神经网络只能学习表情管理丰富的对象的表情,而表情麻木的对象是无法被学习的。 1.AI换脸效果 先看朱茵版黄蓉的原图:再看经过AI换脸后的杨幂版黄蓉:后看视频&#xff1a…...

# 发散创新:用Go语言高效接入InfluxDB实现时序数据采集与可视化在现代微服务架构中,**时序数据

发散创新:用Go语言高效接入InfluxDB实现时序数据采集与可视化 在现代微服务架构中,时序数据的采集与分析已成为系统监控、IoT设备管理以及业务指标追踪的核心能力。InfluxDB凭借其高性能写入和强大的查询能力,成为众多开发者首选的时间序列数…...

李南左日更3327:为什么员工都在摸鱼?是因为你曾经不信任他们

日更原创战略择向第327篇 三元利润增长体系 是一套完整的企业增长方法论 能切实有效地辅助您: 1)战略择向:找对增长引擎,解决方向问题; 2)组织优化:重塑高效组织,解决能力问题&…...

Kubernetes 认证通关指南:CKA/CKS/CKAD 最新题库 + 本地仿真环境 + 模拟考

⚡️ 拒绝无效刷题,一周高效拿下 K8s 认证📌 写在前面:备考 Kubernetes 认证,你踩过哪些坑?备考 CKA、CKS、CKAD 的同学,或多或少都遇到过这些问题: 网上题库零散过时,不知道哪些考点…...

关于旧系统+旧安卓版本realme手机的原生文件管理不支持向微信好友一次性发送多个非照片格式文件的问题和解决方案

关于旧系统+旧安卓版本realme手机的原生文件管理不支持向微信好友一次性发送多个非照片格式文件的问题和解决方案2026年3月18日晚上回家吃饭的路上,我遇到了这样一个问题:我需要对手机上的微信好友一次性分享多个手机内的文件,这些…...

【Xilinx Vivado时序分析/约束系列4】FPGA开发时序分析/约束-实验工程上手实操

目录 建立工程 添加顶层 模块1 模块2 添加约束文件 编辑时钟约束 打开布线设计 代码代表的含义 时序报告 进行时序分析 Summary:包含了汇总的信息量 Source Clock Path:这部分是表示Tclk1的延时细节 Data Path:数据路径的延时 往…...

【Xilinx Vivado时序分析/约束系列3】FPGA开发时序分析/约束-保持时间

目录 基本概念 数据结束时间(Data finish time) 时钟到达时间(Clock arrival time) 保持时间门限 保持时间余量(Hold Slack) 往期系列博客: 基本概念 数据结束时间(Data fini…...

具身智能中 Wrapper 架构的深度解构与 Python 实战

具身智能中 Wrapper 架构的深度解构与 Python 实战零、前言 在具身智能(Embodied AI)的开发中,我们常常需要让智能体(Agent)在仿真环境(如 Isaac Sim, Mujoco, PyBullet)中进行千万次的试错训练…...

【Xilinx Vivado时序分析/约束系列2】FPGA开发时序分析/约束-建立时间

目录 基本概念 数据结束时间(Data finish time) 保持时间门限 保持时间余量(Hold Slack) 基本概念 数据结束时间(Data finish time) 之前解释了数据达到的时间,对于data arrival time Tc…...

【常见错误】Xilinx Vivado自带编辑器文字部分出现乱码解决办法

一、发现问题在进行FPGA开发时,常用的代码编辑器比如Sublime,但是最近发现再Sublime中编辑的代码文字部分,在用Vivado自带的编辑器打开时,会出现文字错乱的情况,如下图:而在Sublime中实际的情况却是下图这样…...

Java SE1(第一章1:概述)

目录 一、java历史 java的发展方向:(要记住) 二、Java语言的特点 【了解】 三、Java运行机制 1. Java运行机制 2. 注意 Java是一种计算机编程语言;除了java编程语言,还有很多的编程语言:c、c、c#、pyt…...

【uniapp】带你优雅的封装uniapp的request请求

封装前的准备先在项目目录上右键 - 新建目录request(用于存放封装的API请求文件),并至少创建两个js文件index.js用于封装get、post请求,接收参数并返回数据api.js用于封装后台接口,便于页面调用和后期维护(…...

Windows 7 驱动安装

Windows 7 驱动安装1. 驱动安装2. 安装驱动和运行环境References1. 驱动安装 驱动精灵 标准版 驱动精灵 万能网卡版 注意:更改安装路径和安装选项 ​​​ 2. 安装驱动和运行环境 避免自行管理混乱。 References [1] Yongqiang Cheng (程永强), https://yongqi…...

Windows 7 旗舰版高效办公 - 任务栏和开始菜单属性

Windows 7 旗舰版高效办公 - 任务栏和开始菜单属性1. 开始 -> 右键 -> 属性2. 任务栏和开始菜单属性3. 自定义开始菜单4. 运行5. cmd6. cmd.exe7. 将此程序锁定到任务栏References1. 开始 -> 右键 -> 属性 2. 任务栏和开始菜单属性 ​​​ 3. 自定义开始菜单 运…...

vue3 - 使用 setup 语法糖时 组件名 name 简写借助插件 vite-plugin-vue-setup-extend → 浏览器中 vue 插件查看组件名可自定义(而非组件文件名)

目录 之前写两个 script 使用插件 `vite-plugin-vue-setup-extend` 使用插件后一个 script 想要浏览器中 vue 插件查看组件名可自定义(而非组件文件名) 之前写两个 script <template><div class="person"><h2>姓名:{{ name }}</h2><h…...

Pampy与函数式编程:如何构建更优雅的Python应用

Pampy与函数式编程&#xff1a;如何构建更优雅的Python应用 【免费下载链接】pampy Pampy: The Pattern Matching for Python you always dreamed of. 项目地址: https://gitcode.com/gh_mirrors/pa/pampy 在Python开发中&#xff0c;函数式编程范式正逐渐成为提升代码可…...

NutsDB迭代器使用详解:如何高效遍历海量数据

NutsDB迭代器使用详解&#xff1a;如何高效遍历海量数据 【免费下载链接】nutsdb 项目地址: https://gitcode.com/gh_mirrors/nut/nutsdb NutsDB是一款高性能的嵌入式键值数据库&#xff0c;提供了强大的数据遍历能力。迭代器&#xff08;Iterator&#xff09;作为Nuts…...

html-docx-js图片处理完全指南:解决Base64图像转换的3个关键技巧

html-docx-js图片处理完全指南&#xff1a;解决Base64图像转换的3个关键技巧 【免费下载链接】html-docx-js Converts HTML documents to DOCX in the browser 项目地址: https://gitcode.com/gh_mirrors/ht/html-docx-js 在浏览器端将HTML文档转换为DOCX格式时&#xf…...

Kiali与外部服务集成:Grafana、Jaeger和Prometheus的无缝连接指南

Kiali与外部服务集成&#xff1a;Grafana、Jaeger和Prometheus的无缝连接指南 【免费下载链接】kiali Kiali project, observability for the Istio service mesh 项目地址: https://gitcode.com/gh_mirrors/ki/kiali 在Istio服务网格的监控和可观测性领域&#xff0c;K…...

Nord tmux主题工作原理揭秘:从配置文件到色彩方案的实现

Nord tmux主题工作原理揭秘&#xff1a;从配置文件到色彩方案的实现 【免费下载链接】tmux An arctic, north-bluish clean and elegant tmux color theme. 项目地址: https://gitcode.com/gh_mirrors/tmux/tmux 什么是Nord tmux主题&#xff1f; Nord tmux主题是一款以…...

Apache NuttX文件系统实战:FAT、ROMFS、NFS等12种文件系统详解

Apache NuttX文件系统实战&#xff1a;FAT、ROMFS、NFS等12种文件系统详解 【免费下载链接】nuttx 项目地址: https://gitcode.com/gh_mirrors/in/incubator-nuttx Apache NuttX是一款高度可配置的实时操作系统&#xff08;RTOS&#xff09;&#xff0c;广泛应用于嵌入…...

7分钟掌握RuboCop:Ruby代码质量终极守护者指南

7分钟掌握RuboCop&#xff1a;Ruby代码质量终极守护者指南 【免费下载链接】rubocop 项目地址: https://gitcode.com/gh_mirrors/rubo/rubocop RuboCop是Ruby社区最受欢迎的代码质量检查工具&#xff0c;它不仅能自动检测代码中的风格问题和潜在错误&#xff0c;还能帮…...