Skip to content

线程(内核级与用户级)

2026 大纲 二(一)3 线程的实现,补充说明点名内核支持的线程线程库支持的线程两类。

线程由谁管,决定它的一切

进程基本概念已经说清了线程是怎么来的—— 把"资源拥有者"和"调度对象"两个身份拆开,资源留给进程、调度给线程。

但那只说了为什么要有线程,没说线程由谁来管。而这个问题的答案, 决定了线程的全部性质。

有两种做法。线程可以由用户空间的一个线程库自己管—— 库里维护一张线程表、自己决定切给谁、切换就是在用户态换一组寄存器。 内核对此一无所知,它眼里只有一个进程。这是用户级线程(ULT)

也可以由内核来管——内核为每个线程建一个控制块(TCB)、 把线程当成调度单位排进就绪队列。这是内核级线程(KLT)

这一刀切下去,后面所有差别都是它的推论,一条都不用单独记:

内核不认识线程 ⇒ 它没法把同一进程的两个线程派到两个核上 ⇒ ULT 用不了多核; 内核不认识线程 ⇒ 某个线程发了阻塞式系统调用时,内核只知道"这个进程在等 I/O" ⇒ 一个线程阻塞,整个进程都阻塞; 反过来,切换不需要内核参与 ⇒ 不用陷入内核态,切换最快, 而且调度算法可以由应用自己定

KLT 恰好反过来:能用多核、一个阻塞不影响别的,代价是每次切换都要陷入内核、 创建和管理开销更大。

读这一节只需盯住那一刀:内核认不认识它。剩下的都能推。

一、两类线程的分界

考纲用词教材用词缩写分界判据
内核支持的线程内核支持线程 KST / 内核级线程KLT线程的创建、阻塞、撤销、切换都在内核空间实现,内核为每个线程建 TCB,调度以线程为单位
线程库支持的线程用户级线程ULT线程的创建、撤销、同步、调度全部由用户空间的线程库完成,内核完全不知道线程存在,调度仍以进程为单位

TCB 里具体存哪些字段、与 PCB 有什么对应关系,见 进程的组织与控制

二、两类线程的优缺点,逐条从那一刀推出来

ULT(线程库支持)KLT(内核支持)
切换开销不需转入内核空间,管理数据结构与切换代码都在用户空间要经"用户态→内核态→用户态"模式切换,但不换地址空间,仍比进程切换快
调度算法可以是进程专用的,不同进程各选各的归内核的低级调度管
移植性可在不支持线程机制的 OS 上实现(属用户程序的一部分)依赖内核支持
一个线程阻塞整个进程阻塞(大多数系统调用是阻塞型的)内核可调度同进程的其他线程占用处理机
多处理机用不了:内核每次只给一个进程分配一个 CPU同时调度同一进程的多个线程并行执行
创建与管理开销大:每个线程都要建 TCB、分配栈空间
附带时间片按进程分配,对进程内线程数不敏感内核自身也可采用多线程技术

三、组合方式与三种多线程模型

内核支持多个内核线程的建立、调度和管理,同时也允许应用程序建立、调度和管理用户级线程;若干内核支持线程对应多个用户级线程,由用户级线程通过时分多路复用内核支持线程来实现,程序员可按应用需要和机器配置调整内核支持线程的数目。效果是两个缺点同时被拿掉:同进程的多个线程可以在多处理机上并行,且阻塞一个线程不必阻塞整个进程

实现组合方式的中间层是内核控制线程,又称轻型进程 LWP

  • 每个进程可拥有多个 LWP,每个 LWP 有自己的数据结构(如 TCB),包括线程标识符、优先级、状态、栈和局部存储区——正因为它自带这一套,它才是内核看得见、调度得动的实体;
  • LWP 可通过系统调用获得内核服务。一个用户级线程只要连接到某个 LWP 上,就具有了内核支持线程的全部属性
  • 用户级线程可能很多,不可能配同样多的 LWP,于是把 LWP 做成缓冲池即线程池。多个用户级线程可多路复用同一个 LWP,但只有当前连接在 LWP 上的线程才能与内核通信,其余的或阻塞、或等待 LWP。
模型映射关系能否用多核一个线程阻塞的后果主要代价
多对一多个 ULT → 1 个内核控制线程不能:任一时刻只有一个线程能访问内核整个进程都被阻塞并发度受限
一对一1 个 ULT → 1 个 KLT能:多线程可并行运行在多处理机上只阻塞该线程,可调度另一个线程运行每建一个用户线程就要建一个内核线程,开销大,需限制系统线程总数
多对多m 个 ULT → n 个 KLT(m ≥ n)只阻塞该线程实现复杂

四、线程切换 vs 进程切换:开销的量化口径

这笔账用户级线程切换同进程内的内核级线程切换进程切换
保存/恢复通用寄存器、PC、PSW要(存进线程自己的栈)要(存进 TCB)要(存进 PCB)
用户态↔内核态模式切换不需要需要(一进一出)需要
切换地址空间(换页表基址寄存器 PTBR)不需要不需要需要
TLB 是否失效不会不会(未做地址空间标识时须整体刷新,此后一段时间连续 TLB 缺失)
Cache 命中率基本不受影响基本不受影响显著下降(工作集换人)

地址变换的细节见 页式管理,切换过程本身见 上下文切换机制

把三种切换的开销算成具体数字,看清差距落在哪一笔上(想量化"尽量把协作任务放进同一个进程"时展开)

设某单处理机实测:一次模式切换 0.4 µs;保存并恢复一套执行现场 1.2 µs;切换 PTBR 0.3 µs;TLB 整体失效导致的后续重填折算 3.0 µs;用户级线程切换全程在用户态,实测 0.5 µs。

按上表逐笔加——每种方案只把它真正发生的那几笔算进去:

tULT=0.5 μs(纯用户态,无模式切换、无地址空间切换)tKLT=2×0.4进出内核+1.2现场=2.0 μst进程=2×0.4进出内核+1.2现场+0.3换 PTBR+3.0TLB 重填=5.3 μs

KLT 比进程切换少 3.3 µs,全部来自同进程线程共享页表,PTBR 不动、TLB 不失效。10000 次切换:ULT 5 ms、KLT 20 ms、进程 53 ms,比为 1 : 4 : 10.6

若其中 30% 必须跨进程、70% 是同进程内的 KLT 切换,必须按比例加权(两种切换的单次代价差 2.65 倍,不能取端点平均):

t¯=0.3×5.3+0.7×2.0=2.99 μs,T=29900 μs=29.9 ms

比纯 KLT 方案多 49.5%——仅 30% 的切换跨了进程,总开销就涨了近一半。

变一个条件结论就变:若 TLB 带地址空间标识(进程切换无须整体刷新),t进程 降为 2.3 μs,与同进程线程切换只差 0.3 µs,那 49.5% 会缩到 4.5%。"进程切换贵"贵在 TLB 那一笔上。

考点速记

  1. 两类线程的分界只有一刀——内核认不认识线程。 能不能用多核、一阻塞会不会全阻塞、切换进不进内核态,全是它的推论。
  2. ⚠️只有内核级线程有 TCB(线程控制块)。用户级线程由用户空间的线程库自己维护线程表,操作系统不为它建 TCB、也不为它做调度
  3. ⚠️用户级线程不由操作系统创建,由线程库创建;内核级线程才由操作系统创建
  4. ULT 的优点:切换与调度都在用户空间完成、不陷入内核,效率高;调度算法可由应用自选;可以在不支持内核级线程的操作系统上实现
  5. ULT 的代价:某线程发出阻塞式系统调用时整个进程阻塞(内核只看见进程);用不了多核(内核派不出去)。
  6. 线程私有的(每条执行流有自己的调用链)、寄存器与 PC、TCB / 线程标识。⚠️栈指针也是私有的——它就是"这条执行流走到哪了"的一部分。
  7. 线程共享的进程的地址空间、代码段、数据段(全局变量)、堆、打开的文件(fd)。⚠️堆是共享的、栈是私有的,这一对在下面四道题里出现了三次。
  8. ⚠️**"进程栈"这个说法要留意:同一进程下的多个线程各有各的栈,不共享;共享的是堆**。
  9. 映射方向不能反:多个用户级线程可以映射到一个内核级线程(多对一),不存在"多个内核级线程映射到一个用户级线程"——用户级线程是被映射方,不是承载方。
  10. 纯用户级线程等价于多对一模型;组合方式用 LWP 当中间层,同时拿掉两个缺点。
  11. 线程切换比进程切换便宜,最大的一笔是不换地址空间(页表基址寄存器不动、TLB 不失效)。

这一节在真题里被考过的形式

四道题里三道是"判断线程的若干条描述",而且每道都至少有一项在考"谁私有谁共享"。 这一节可以说只有两个考点:谁管(第一到五条)谁共享(第六到八条)

  • 问进程 P 创建的若干线程不能共享的是什么(2011-25)。答进程 P 中某线程的栈指针。⚠️ 另三项(代码段、打开的文件、全局变量)全是共享的——它们属于进程这个资源容器。判据是速记第六条:栈和栈指针刻画的是"这条执行流走到哪了",换一条执行流就得换掉它
  • 判断线程的四条描述,选错误的(2019-23)。错项是"操作系统为每个用户级线程建立一个线程控制块"——OS 根本不知道用户级线程的存在(速记第二条)。另三条都对:内核级线程的调度由 OS 完成、用户级线程间切换效率更高、用户级线程可以在不支持内核级线程的 OS 上实现。
  • 问线程 T 创建线程 Ta 后,Ta 能与 T 共享哪些(2024-28)。答进程 P 的地址空间 + fd 两项;⚠️线程 T 的栈不共享。这道题把"共享容器里的东西、不共享执行流自己的东西"这条判据摆得最清楚——fd 属于进程的打开文件表,栈属于某一条执行流。
  • 判断线程的四条描述,选正确的(2026-25)。答同一个进程下的多个线程共享进程堆。⚠️ 另三项各错一处:"内核级线程和用户级线程都由操作系统创建"错(用户级由线程库创建,速记第三条);"多个内核级线程可以映射到一个用户级线程"把映射方向说反了(速记第九条);"同一进程下的多个内核级线程共享进程栈"错——栈是私有的(速记第八条)。

复习优先级必须拿满,两组判据全部要背。 一组是"内核认不认识它"及其五条推论, 另一组是"栈私有、堆共享"这条分界(问法每年换,判据不变)。 第九条那个映射方向是 2026 年新出的坑,要单独记。 LWP 与三种多线程模型至今没单独考过,理解即可。

易错:认为 OS 会为用户级线程建立 TCB。OS 根本不知道用户级线程的存在

易错:认为用户级线程也由操作系统创建。由线程库创建;内核级线程才由 OS 创建。

易错:认为同一进程下的多个线程共享栈。栈是私有的、堆是共享的——这一对每年换着问法考。

易错:认为栈指针是共享的。它是"这条执行流走到哪了"的一部分,私有

易错:把映射方向说反。多个用户级线程映射到一个内核级线程,反过来不成立。

易错:认为用户级线程能利用多核。内核派不出去——它眼里只有一个进程。

易错:认为线程切换和进程切换开销差不多。最大的一笔差别是线程切换不换地址空间(TLB 不失效)。

教材出处
  • 汤小丹《计算机操作系统》2.7.2、2.7.3,印刷 p77–p78:线程仅拥有 TCB、程序计数器、一组寄存器和堆栈;线程的三种状态;"在把某个进程挂起时,该进程中的所有线程也都将被挂起"
  • 汤小丹《计算机操作系统》2.8.1 线程的实现方式,印刷 p79–p81:内核支持线程 KST 的四条优点与模式切换缺点;用户级线程 ULT 的三条优点与两条缺点(系统调用阻塞问题、不能利用多处理机);组合方式 ULT/KST;三种多线程模型
  • 汤小丹《计算机操作系统》2.8.2 线程的实现,印刷 p81–p82:内核支持线程的任务数据区 PTDA 与 TCB 组织,撤销线程时保留 TCB 供复用;运行时系统的定义与用户态切换步骤;轻型进程 LWP 与线程池
  • 孙钟秀、费翔林《操作系统教程》(第 6 版)2.4.2 内核级线程与用户级线程,印刷 p67–p68:线程库是"用户级线程管理的例行程序包,主要功能有线程的创建、调度、管理",是线程的运行支撑环境;Jacketing 技术

相关知识

进程基本概念进程状态与转换进程的组织与控制上下文切换机制多处理机调度

真题练习

相关真题(1题)