Skip to content

2012年 408 操作系统 第 28 题

操作系统2012年选择题2分

题目

若一个用户进程通过 read 系统调用读取一个磁盘文件中的数据,则下列关于此过程的叙述中,正确的是( )。 Ⅰ. 若该文件的数据不在内存中,则该进程进入睡眠等待状态

Ⅱ. 请求 read 系统调用会导致 CPU 从用户态切换到核心态

Ⅲ. read 系统调用的参数应包含文件的名称

错因

B

承认 Ⅰ Ⅱ 而把 Ⅲ"参数含文件名"也勾上——但 read 接受的是文件描述符 fd(一个小整数),不是文件名。文件名在 open 时使用,open 返回 fd,read 用 fd 操作。把 read 当成 open 来用是这道题最常见的混淆。

C

承认 Ⅱ Ⅲ 漏 Ⅰ——其实 read 在数据不在内存时必然会让进程睡眠等磁盘 I/O。把"read 不在内存就阻塞"当成不对的,可能是默认 OS 总是把数据预取到缓存里、read 总是命中——但即使 page cache 命中很高,第一次访问仍要等 I/O。

D

把 Ⅲ 也选了——同 B 的错。read 的参数只有 (fd, buf, count),没有文件名。

总解析

read(fd, buf, count) 的标准语义:

c
ssize_t read(int fd, void *buf, size_t count);

参数:

  • fd:文件描述符(前面 open 返回的)
  • buf:用户空间缓冲区指针
  • count:要读多少字节

没有文件名——文件名在 open 时已经解析过、转成 fd 了,read 只用 fd。

逐条核对:

命题描述判定说明
数据不在内存 → 进入睡眠read 是同步阻塞调用——数据不在 page cache 时进程被挂起等磁盘 I/O,是典型的"运行 → 阻塞"
切换到核心态系统调用必切——trap 指令陷入内核
参数含文件名参数是 fd 而非文件名——文件名在 open 时使用,read 只用 fd

read 的工作流程

用户进程 read(fd, buf, count)
   ↓ trap → 内核态  ← Ⅱ 切换
内核根据 fd 查打开文件表 → 找到 inode

检查数据是否在 page cache
   命中 → copy 到用户 buf → 返回
   未命中 → 发起磁盘 I/O

         进程进入阻塞态(睡眠)  ← Ⅰ 睡眠

         I/O 完成中断 → 唤醒进程

         copy 到 buf → 返回

正确的是 Ⅰ Ⅱ。

最终答案是 A

最后更新:

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