CppGuide社区 CppGuide社区
首页
  • 最新谷歌C++风格指南(含C++17/20)
  • C++17详解
  • C++20完全指南
  • C++23快速入门
  • C++语言面试问题集锦
  • 🔥C/C++后端开发常见面试题解析 (opens new window)
  • 网络编程面试题 (opens new window)
  • 网络编程面试题 答案详解 (opens new window)
  • 聊聊WebServer作面试项目那些事儿 (opens new window)
  • 字节跳动面试官现身说 (opens new window)
  • 技术简历指南 (opens new window)
  • 🔥交易系统开发岗位求职与面试指南 (opens new window)
  • 第1章 高频C++11重难点知识解析
  • 第2章 Linux GDB高级调试指南
  • 第3章 C++多线程编程从入门到进阶
  • 第4章 C++网络编程重难点解析
  • 第5章 网络通信故障排查常用命令
  • 第6章 高性能网络通信协议设计精要
  • 第7章 高性能服务结构设计
  • 第8章 Redis网络通信模块源码分析
  • 第9章 后端服务重要模块设计探索
  • 🚀 全部章节.pdf 下载 (opens new window)
  • 源码分析系列

    • leveldb源码分析
    • libevent源码分析
    • Memcached源码分析
    • TeamTalk源码分析
    • 优质源码分享 (opens new window)
    • 🔥远程控制软件gh0st源码分析
  • 从零手写C++项目系列

    • C++游戏编程入门(零基础学C++)
    • 🔥使用C++17从零开发一个调试器 (opens new window)
    • 🔥使用C++20从零构建一个完整的低延迟交易系统 (opens new window)
    • 🔥使用C++从零写一个C语言编译器 (opens new window)
    • 从零用C语言写一个Redis
  • Windows 10系统编程
  • Go语言特性

    • Go开发实用指南
    • Go系统接口编程
    • 高效Go并发编程
    • Go性能调优
    • Go项目架构设计
  • Go项目实战

    • 使用Go从零开发一个数据库
    • 🔥使用Go从零开发一个编译器 (opens new window)
    • 🔥使用Go从零开发一个解释器 (opens new window)
    • 🔥用Go从零写一个编排器(类Kubernetes) (opens new window)
  • Rust编程

    • Rust编程指南
  • 数据库

    • SQL零基础指南
    • MySQL开发与调试指南
  • Linux内核

    • 心中的内核 —— 在阅读内核代码之前先理解内核
    • 🔥Linux 5.x内核开发与调试 完全指南 (opens new window)
    • TCP源码实现超详细注释版.pdf (opens new window)
GitHub (opens new window)
首页
  • 最新谷歌C++风格指南(含C++17/20)
  • C++17详解
  • C++20完全指南
  • C++23快速入门
  • C++语言面试问题集锦
  • 🔥C/C++后端开发常见面试题解析 (opens new window)
  • 网络编程面试题 (opens new window)
  • 网络编程面试题 答案详解 (opens new window)
  • 聊聊WebServer作面试项目那些事儿 (opens new window)
  • 字节跳动面试官现身说 (opens new window)
  • 技术简历指南 (opens new window)
  • 🔥交易系统开发岗位求职与面试指南 (opens new window)
  • 第1章 高频C++11重难点知识解析
  • 第2章 Linux GDB高级调试指南
  • 第3章 C++多线程编程从入门到进阶
  • 第4章 C++网络编程重难点解析
  • 第5章 网络通信故障排查常用命令
  • 第6章 高性能网络通信协议设计精要
  • 第7章 高性能服务结构设计
  • 第8章 Redis网络通信模块源码分析
  • 第9章 后端服务重要模块设计探索
  • 🚀 全部章节.pdf 下载 (opens new window)
  • 源码分析系列

    • leveldb源码分析
    • libevent源码分析
    • Memcached源码分析
    • TeamTalk源码分析
    • 优质源码分享 (opens new window)
    • 🔥远程控制软件gh0st源码分析
  • 从零手写C++项目系列

    • C++游戏编程入门(零基础学C++)
    • 🔥使用C++17从零开发一个调试器 (opens new window)
    • 🔥使用C++20从零构建一个完整的低延迟交易系统 (opens new window)
    • 🔥使用C++从零写一个C语言编译器 (opens new window)
    • 从零用C语言写一个Redis
  • Windows 10系统编程
  • Go语言特性

    • Go开发实用指南
    • Go系统接口编程
    • 高效Go并发编程
    • Go性能调优
    • Go项目架构设计
  • Go项目实战

    • 使用Go从零开发一个数据库
    • 🔥使用Go从零开发一个编译器 (opens new window)
    • 🔥使用Go从零开发一个解释器 (opens new window)
    • 🔥用Go从零写一个编排器(类Kubernetes) (opens new window)
  • Rust编程

    • Rust编程指南
  • 数据库

    • SQL零基础指南
    • MySQL开发与调试指南
  • Linux内核

    • 心中的内核 —— 在阅读内核代码之前先理解内核
    • 🔥Linux 5.x内核开发与调试 完全指南 (opens new window)
    • TCP源码实现超详细注释版.pdf (opens new window)
GitHub (opens new window)
  • 心中的内核——在阅读内核代码之前先理解内核 专栏说明
  • 01 内核不是进程,而是系统
  • 02 为进程服务:内核的首要职责
  • 03 代码之前的概念图
  • 04 作为分层系统的内核:虚拟、映射、隔离、控制
  • 05 单体形式,协同行为:真正的内核模型
  • 06 内核对象揭示设计——函数仅执行设计
  • 07 无冲突的代码——内核如何在并发风暴中保持安全
  • 08 间接的力量——一个内核如何为所有进程服务
  • 09 内核的设备模型:硬件如何成为/dev
  • 10 内核如何看待内存:不是映射,而是责任
  • 11 内存不是一个地方,而是一个系统
  • 12 内核始终存在——你知道它在哪里吗?
  • 13 不只是代码执行:内核实际执行的内容
  • 14 boot结束之处:内核开始之处
  • 15 从vmlinuz到eBPF:Linux内核内部实际运行的内容
  • 16 无状态CPU,有状态内核:执行如何被协调
  • 17 内核构建的内容——逐层构建
  • 18 内核执行路径:在哪里运行,以及为何重要
  • 19 追踪执行的模板
  • 20 中断不是干扰,而是设计
  • 21 执行是逻辑的,位置是物理的
  • 22 不仅仅是一段代码:每个内核路径内部的过程
  • 23 内核如何自我通信——内部通信工具
  • 24 内核模块仅通过导出符号相互认知
  • 25 搭建组件之间的桥梁
  • 26 libc之外:用户空间与内核的真实通信方式
  • 27 CPU不移动数据——但没有CPU,什么都无法移动
  • 28 时间与精度:内核眼中的CPU执行
  • 29 内核在虚拟化中的角色:理解KVM
  • 30 两个世界,一个CPU:虚拟化中的root操作和非root操作
  • 31 内核与VirtIO:无需模拟的网络驱动程序
  • 32 一切仍由操作系统掌控
  • 33 对齐即理解
  • 34 如果内核不是由 Linus 创建和维护,会怎样?
  • 35 配置并非定制,而是内核的身份标识
  • 36 内存生命周期与塑造它的角色
  • 37 中断如何在不变中演变
  • 38 并发之外的同步机制
  • 39 这从不关乎炒作,始终关乎硬件
  • 40 从意图到I/O:内核如何看待文件、磁盘和设备
  • 41 心中的内核——效率至上而非历史遗留原因:为什么内核仍用C语言开发

05 单体形式,协同行为:真正的内核模型

# 05 单体形式,协同行为:真正的内核模型

Linux 内核在结构上是单体的。其核心子系统——调度、内存管理、文件系统、网络和驱动程序——被编译成单个二进制文件。它们共享一个地址空间,以特权模式运行,并直接相互调用。在结构上没有隔离来分隔组件。但在运行时,内核行为由所有子系统都必须遵循的系统级约束所塑造。

执行上下文决定了内何在任何时刻可以执行的操作。代码在进程、内核线程、中断或软中断(softirq)上下文中运行。进程和内核线程上下文允许睡眠、阻塞、用户内存访问和页面故障(page faults)处理。中断和软中断上下文则不允许。这些路径对时间敏感,并且不能阻塞或进行调度,因为这样做会延迟其他任务。页面故障处理是不允许的,因为解决故障可能涉及 I/O、内存分配或回收,所有这些都需要睡眠。这些约束是全局适用的,并影响每个内核决策。

子系统通过这些共享规则进行交互。调度器避免抢占原子路径。分配器在阻塞前检查上下文和标志。文件系统通过从非阻塞状态到阻塞状态的有序转换来执行 I/O。网络栈从中断上下文开始,经过软中断和工作队列。设备驱动程序延迟无法安全就地完成的工作。这不是惯例,而是设计。子系统将工作通过有效阶段进行处理,而不是一次性处理所有事情。

同步机制也反映了相同的原则。自旋锁(spinlocks)用于原子路径。互斥锁(mutexes)仅在允许睡眠的地方使用。RCU(读-复制-更新)使读取者能够在不锁定的情况下继续操作。顺序锁(Seqlocks)允许对更新进行快速重试。这些原语是基于上下文和访问模式选择的,而不是开发人员的偏好。用法通过宏、断言和在内核中一致执行的规则来验证。

内存访问遵循相同的模型。访问用户内存需要进程上下文。故障处理只能在允许睡眠的地方进行,因为解决故障可能涉及磁盘 I/O 或内存回收。分配行为取决于标志和上下文。同一个函数可能会阻塞、立即返回或失败,具体取决于它在哪里运行。内存管理要考虑可见性、局部性和上下文。

延迟执行将这些层连接起来。从中断开始的工作被传递到软中断,然后到工作队列,最后到内核线程。每个步骤的设计都满足下一步的约束。这种分阶段模型支持 I/O、网络、定时器和驱动程序。

内核被构建为一个二进制文件,但它作为一个协同系统运行。子系统不能独立运行。它们遵循由上下文、时间和并发性定义的共享模型。它在形式上是单体的,但在执行上是模块化和有原则的。

上次更新: 2025/06/17, 19:51:40
04 作为分层系统的内核:虚拟、映射、隔离、控制
06 内核对象揭示设计——函数仅执行设计

← 04 作为分层系统的内核:虚拟、映射、隔离、控制 06 内核对象揭示设计——函数仅执行设计→

最近更新
01
第二章 关键字static及其不同用法
03-27
02
第一章 auto与类型推导
03-27
03
第四章 Lambda函数
03-27
更多文章>
Copyright © 2024-2025 沪ICP备2023015129号 张小方 版权所有
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式