Appearance
题目
下列选项中,通过系统调用完成的操作是( )。
错因
A
把"页置换"想成了应用程序主动发起的事。但页置换是 OS 内核自己的家务活——缺页时 OS 内核内部决定换哪一页,整个流程在内核态完成,用户进程根本感知不到(只觉得这条 mov 指令慢了一点)。它不是用户态发起的、不需要也没有对应的系统调用。
B
跟 A 是同类错误:进程调度是 OS 内部的决策——时钟中断到、I/O 完成、进程阻塞等事件触发调度器去重新选下一个进程。整个过程是 OS 自己跑的,用户进程不发起也不参与。yield() 这类"让出 CPU"的系统调用是个触发器,但它本身不是"进程调度"这个动作。
D
把"生成随机整数"想成了必须找内核要的服务。其实标准 C 库的 rand() / srand() 完全在用户态用线性同余之类的算法算出来——一段普通的算术代码,不跨态。只有要"密码学强随机"才需要陷入内核读 /dev/urandom,但题面说的是普通的"随机整数",库函数就够了。
总解析
系统调用 = 用户进程主动跨过用户态 / 内核态边界、请求 OS 提供服务的入口。判定一件事是不是系统调用,看两点:
- 谁发起:用户进程主动发起 → 候选;OS 内部自发完成 → 不是
- 是否需要内核权限:触及硬件、跨进程、改 OS 全局状态 → 需要
逐个分析:
| 选项 | 谁发起 | 需要内核权限吗 | 是系统调用吗 |
|---|---|---|---|
| A 页置换 | OS 内部(缺页时自动) | — | ✗ 内核内部活动 |
| B 进程调度 | OS 内部(事件驱动) | — | ✗ 内核内部活动 |
| C 创建新进程 | 用户进程(fork、CreateProcess) | 是(要分配 PCB、地址空间、文件描述符等内核资源) | ✓ 标准系统调用 |
| D 生成随机整数 | 用户进程 | 否(C 库 rand() 用户态算就行) | ✗ 普通库函数 |
fork / exec / CreateProcess 是创建新进程的标准系统调用入口——必须由 OS 内核分配 PCB、建立地址空间、设置文件描述符表等。这些动作用户态做不了,必须陷入内核。
最终答案是 C。