{T}

操作系统内核与态切换

本文整理内核的职责与分类,以及用户态/内核态的划分、系统调用切换过程和用户态线程与内核态线程的映射模型。

一、内核的职责

内核(Kernel)是操作系统连接应用与硬件的桥梁,至少提供以下 4 种基本能力:

  • 进程/线程管理:决定哪个进程、线程使用 CPU。
  • 内存管理:决定内存如何分配与使用。
  • 硬件设备连接:为进程与设备之间提供通信能力。
  • 系统调用:接收进程发起的系统调用请求。

操作系统通常分为三层:最底层硬件设备抽象、中间的内核、最上层应用。

![操作系统分层](/os-images/14-操作系统内核:Linux 内核和 Window 内核有什么区别__CgqCHl-P5meAd3VdAAB1f7DWz-I273.png)

内核的工作模型

进程与内核之间采用类似请求/响应的模型:进程向内核发起请求,让出 CPU 执行权限;内核接手 CPU,完成请求后再将执行权限交还调用进程。这一隔离是必需的——内核可直接访问全部内存、管理所有进程,必须与进程之间保持权限边界。

![进程-内核请求响应模型](/os-images/14-操作系统内核:Linux 内核和 Window 内核有什么区别__CgqCHl-P5naAc5fsAABuTlhIQkw555.png)

二、内核的分类

宏内核(Monolithic Kernel)

Linux 采用宏内核架构:内核是一个完整的可执行程序,以最高权限运行,文件系统、驱动、内存管理等大多打包在内核中。现代 Linux 支持动态加载内核模块,无需重新编译内核即可安装驱动。

微内核(Microkernel)

微内核只保留最基本能力(进程调度、虚拟内存、中断),驱动、文件系统等多数功能放在用户空间管理。其优势是体积小、可移植性强;代价是驱动与硬件交互需频繁进行内核态切换,性能开销较大。

![宏内核与微内核对比](/os-images/14-操作系统内核:Linux 内核和 Window 内核有什么区别__CgqCHl-QEKSAYD22AAFXRfj1rsA581.png)

混合内核(Hybrid Kernel)

架构上抽象出微内核(内部有最小内核模块),但实现上用宏内核方式——整体作为一个完整程序,包含大量功能。Windows NT 属于混合内核。

三、Linux 与 Windows 内核对比

维度LinuxWindows NT
内核类型宏内核混合内核
开源
可执行文件格式ELF(Executable and Linkable Format)PE(Portable Executable,.exe/.dll/.sys
多任务/多处理支持 Multitask、SMP支持 Multitask、SMP
虚拟化KVM 等Hyper-V

两者均支持对称多处理(SMP):各处理器地位平等,共享内存与硬件资源,任务可被调度到任意处理器执行。

ELF 将可执行文件划分为多个段(Segment),每段有特定用途;PE 结构与之相通。

四、用户态与内核态

内核运行在超级权限模式(Supervisor Mode),内存因此被划分为两部分:

  • 内核空间(Kernel Space):仅内核程序可访问。
  • 用户空间(User Space):专供应用程序使用。

用户空间代码被限制只能使用一个局部内存空间,称为运行在用户态(User Mode);内核空间代码可访问全部内存,称为运行在内核态(Kernel Mode)

系统调用过程

用户态程序需要执行特权指令时必须切换到内核态。过程如下(图中 Trap 即一种中断):

系统调用切换

  1. 用户态程序发起系统调用,因权限不足触发 Trap(中断)。
  2. CPU 跳转至中断处理程序,内核开始处理系统调用。
  3. 内核处理完成后主动触发 Trap,再次中断切换回用户态。

五、进程与线程

应用程序启动后在内存中创建执行副本,即进程。进程可分成用户态进程(应用程序副本)与内核态进程(内核自身进程)。现代操作系统以**线程(Thread,轻量级进程 LWP)**为执行单位,一个进程可拥有多个线程。

线程的创建位置有两种选择:用户态(用户空间 API)或内核态(系统调用)。

六、用户态线程与内核态线程

用户态线程(User Level Thread)

完全在用户空间创建,内核不知其存在。

优势:

  • 管理开销小,创建/销毁无需系统调用;
  • 切换成本低,由用户空间程序自行维护调度。

劣势:

  • 与内核协作成本高:进行 I/O 时需频繁切换内核态;
  • 线程间通信需经 I/O 与系统调用,额外成本高;
  • 无法利用多核:操作系统只调度所属进程,进程内多线程只能并发执行一个;
  • 操作系统无法感知阻塞:某用户态线程阻塞时,OS 不会切换其他线程,造成资源浪费。

内核态线程(Kernel Level Thread)

执行在内核态,通过系统调用创建。

优势:

  • 可利用多核 CPU;
  • 操作系统级优化:线程 I/O 不需系统调用,一个线程阻塞可立即切换另一个。

劣势:

  • 创建成本高(需系统调用);
  • 扩展性差(由内核统一管理,数量受限);
  • 切换成本较高(需内核操作)。

七、用户态线程与内核态线程的映射

用户态线程创建成本低但无法利用多核,内核态线程可利用多核但创建/切换成本高。常见做法是在内核中预创建并复用一批内核线程,用户态线程附着其上执行。两者存在 4 种映射关系:

多对一(Many to One)

多个用户态线程复用 1 个内核态线程。创建成本低,但线程无法并发,现已很少使用。

多对一

一对一(One to One)

每个用户态线程绑定 1 个独立内核态线程,允许全部线程并发、充分利用多核。Windows NT 采用此模型,但内核调度压力大。

一对一

多对多(Many to Many)

n 个用户态线程分配 m 个内核态线程((m \le n),常取 (m=) 核数)。兼顾内核线程数量与多核并发,Linux 目前采用此模型。

多对多

两层设计(Two Level)

混合多对多与一对一:多数用户态线程为 n 对 m,少量用户线程可指定为 1 对 1。

两层设计

小结

  • 内核提供进程/内存/设备/系统调用四大能力,按架构分为宏内核、微内核、混合内核。
  • 内存划分为内核空间与用户空间,特权操作经 Trap 切换内核态完成系统调用。
  • 用户态线程轻量但无法用多核,内核态线程可用多核但开销大;两者通过多对一、一对一、多对多、两层四种模型映射。