Appearance
题目
下列关于线程的描述中,正确的是( )。
错因
A
混淆了"线程实体"和"调度实体"。用户级线程(ULT)是用户态线程库(如早期 pthread 的纯用户态实现、Java 的 GreenThread)创建和管理的——OS 内核根本不知道它们存在,只看到一个普通的单线程进程。只有内核级线程(KLT)才由 OS 创建和调度。"OS 创建了所有线程"的印象往往来自只接触过 Linux NPTL 这种 1:1 模型的人,把 KLT 当作了线程的全部。
B
把多对一模型的方向反着记了。线程的三种映射模型:
- 多对一(M:1):多个 ULT → 一个 KLT(用户线程库自己调度,OS 看不到)
- 一对一(1:1):每个 ULT → 一个 KLT(Linux NPTL、Windows 的标准模型)
- 多对多(M:N):M 个 ULT → N 个 KLT(M ≥ N,混合模型)
选 B 的人把"多对一"颠倒成了"多个 KLT 映射到一个 ULT"——但这反过来说不通:如果一个 ULT 后面跟着多个 KLT,等于一个用户线程要同时占用多个内核调度实体,没有任何意义。
C
把"栈"和"堆"搞反了。线程的资源划分是经典考点:
- 每个线程私有:栈、寄存器、PC、TCB(线程控制块)
- 同进程内所有线程共享:堆、全局变量、代码段、打开的文件描述符、信号处理器
栈必须独立——否则函数调用层次会互相覆盖,没法正确返回。所以 C 把"共享栈"当作正确说法是错的。
总解析
逐项判断:
| 选项 | 关键论断 | 对错 | 理由 |
|---|---|---|---|
| A | 两类线程都由 OS 创建 | ✗ | 用户级线程由用户线程库创建,OS 不可见 |
| B | 多个 KLT → 一个 ULT | ✗ | 多对一模型方向反了,应是多个 ULT → 一个 KLT |
| C | 同进程的 KLT 共享进程栈 | ✗ | 线程私有栈;共享的是堆、全局区、代码段 |
| D | 同进程的多个线程共享进程堆 | ✓ | 线程的核心特征——共享地址空间内的堆和全局数据 |
核心知识点:
- 谁创建:用户级线程 → 用户线程库;内核级线程 → 操作系统
- 谁私有:栈、寄存器、PC、TCB
- 谁共享:堆、全局变量、代码段、打开文件、地址空间
线程的"轻",正是因为共享了进程的大部分资源(堆、代码、文件),切换时只需保存/恢复少量私有数据(寄存器和栈指针)。
最终答案是 D。