Skip to content

2024年 408 操作系统 第 28 题

操作系统2024年选择题2分

题目

若进程 P 中有一个线程 T,打开文件后获得 fd,再创建线程 Ta、Tb,则线程 Ta、Tb 可共享的资源是( )。

Ⅰ. 进程 P 的地址空间 Ⅱ. 线程 T 的栈 Ⅲ. fd

错因

A

不确定 fd 是否可以共享——"fd 是 T 打开的,会不会只属于 T?"于是只敢勾选 Ⅰ。但 fd 是进程级资源:内核里只有一张 per-process 文件描述符表,fd 就是这张表的下标,不属于哪个线程私有。任何同进程的线程都能用同一个 fd 读写,这正是多线程并发 I/O 的基础。

C

把"地址空间"和"栈"搞反了——以为线程共享栈、不共享地址空间。但线程"轻量"特性恰恰来自共享地址空间(堆、全局变量、代码段都共用),只有栈和寄存器是线程私有的。Ⅰ Ⅱ 反过来记是经典错误,需特别注意。

D

没注意 Ⅱ 写的是"T 的栈"——以为题意是"T 的所有资源都被 Ta、Tb 继承共享",于是三项全选。但栈是线程私有资源——T 的栈只属于 T,Ta 和 Tb 各有自己独立的栈。如果 Ta 能访问 T 的栈,函数调用层次会互相破坏,根本无法工作。

总解析

核心知识点:线程的私有 vs 共享资源——

类别资源
线程私有栈、寄存器、PC、TCB(线程控制块)、TLS(线程局部存储)
进程级共享(同进程线程共享)地址空间(堆、全局变量、代码段、数据段)、文件描述符表、信号处理器、当前工作目录、UID/GID

逐项核验

描述共享?理由
进程 P 的地址空间进程级资源,所有线程共享
线程 T 的栈栈是线程私有,T 的栈只能 T 自己用
fdfd 在进程级文件描述符表中,所有线程通用

关键陷阱在 Ⅱ:题面说的是"T 的栈"——栈本来就是线程私有的,T 的栈是 T 独占,Ta 和 Tb 各有自己的栈。问"Ta、Tb 共享 T 的栈"——这个问法本身就站不住,因为栈不是设计来共享的。

为什么 fd 可以共享

进程 P
├── 文件描述符表(进程级,唯一)
│   ├── fd=3 → 指向 /tmp/foo 的 file 结构
│   └── ...
├── 线程 T(私有栈、寄存器)
├── 线程 Ta(私有栈、寄存器)
└── 线程 Tb(私有栈、寄存器)

T 调用 open() 拿到的 fd,本质上是 P 的 fd 表里的一个下标——这张表是 P 的,不是 T 的。Ta 和 Tb 直接 read(fd, ...)write(fd, ...) 都能用同一个 fd,这正是多线程并发 I/O 的常见模式(如多线程 Web Server 共享 socket fd 处理同一个连接)。

速记

  • 共享 = "属于进程的"(地址空间、文件描述符表)
  • 私有 = "属于线程的"(栈、寄存器、PC)
  • 题面给出的"T 的栈"——名字里就带"T 的",私有无疑

最终答案是 B

最后更新:

⚠️ 这道题暂未配可视化,欢迎在 CodeBrick 反馈区告诉我们你想看哪道题