2014年408真题操作系统篇


23. 下列调度算法中,不可能导致饥饿现象的是( )

A. 时间片轮转 B. 静态优先数调度 C. 非抢占式短作业优先 D. 抢占式短作业优先


✅ 正确答案:A. 时间片轮转


解释:

饥饿(Starvation)现象:指某些进程长时间得不到系统资源(如 CPU)分配,始终处于等待状态,无法执行。

各选项分析如下:

  • A. 时间片轮转(Round Robin) 每个进程按时间片轮流获得 CPU,即使优先级低,也一定会轮到 → ✅ 不会造成饥饿。
  • B. 静态优先数调度 优先级一旦设定不变,优先级低的进程可能长期得不到执行机会 → ❌ 可能饥饿。
  • C. 非抢占式短作业优先(SJF) 长作业可能一直被短作业排在后面 → ❌ 可能饥饿。
  • D. 抢占式短作业优先 短作业频繁到来,长作业被不断抢占 → ❌ 可能饥饿。

24. 某系统有 n 台互斥使用的同类设备,三个并发进程分别需要3、4、5台设备,可确保系统不发生死锁的设备数 n 最小为( )

A. 9 B. 10 C. 11 D. 12


✅ 正确答案:B. 10


解释:

这是一道死锁避免问题,采用类似银行家算法的思想。

三个进程最大需求:

  • 进程 P1:最多 3 台
  • 进程 P2:最多 4 台
  • 进程 P3:最多 5 台

我们要确保系统中至少留有足够的资源使某个进程能完成执行

❗ 死锁临界情况:

假设:

  • P1 分配 2 台(少 1)
  • P2 分配 3 台(少 1)
  • P3 分配 4 台(少 1) → 系统总共已分配:2 + 3 + 4 = 9 台 → 没有多余的设备了(即 n = 9),但都还差 1 台才能完成,死锁发生!

✅ 避免死锁的最小设备数:

再加 1 台 → n = 10 现在总资源 = 10 台 即便分配了 2 + 3 + 4 = 9 台,还有 1 台空闲,能满足某个进程完成,释放资源,系统进入安全序列 → ✅ 不会死锁。


25. 下列指令中,不能在用户态执行的是( )

A. trap 指令 B. 跳转指令 C. 压栈指令 D. 关中断指令


✅ 正确答案:D. 关中断指令


解释:

现代操作系统将 CPU 指令分为两类:

  • 特权指令(只能在内核态执行)
  • 非特权指令(用户态可执行)

分析各个选项:

  • A. trap 指令 Trap 是一种软中断指令,允许用户程序主动请求操作系统服务(即系统调用),这是一种从用户态到内核态的合法通道,是可以在用户态执行的。✅
  • B. 跳转指令 跳转(如 jmpcall)是普通控制指令,属于用户程序正常执行流程的一部分,可在用户态使用。✅
  • C. 压栈指令push 这样的指令用于函数调用、局部变量处理等,也是普通指令,可在用户态执行。✅
  • D. 关中断指令(如 cli 用于关闭 CPU 中断,这会影响整个系统的中断响应,是特权指令只能在内核态执行。在用户态执行会引发异常。❌

26. 一个进程的读磁盘操作完成后,操作系统针对该进程必做的是( )

A. 修改进程状态为就绪态 B. 降低进程优先级 C. 给进程分配用户内存空间 D. 增加进程时间片大小


✅ 正确答案:A. 修改进程状态为就绪态


解释:

当进程进行 I/O 操作(如磁盘读取)时,会被阻塞(Blocking),进入阻塞态(Blocked),直到操作完成。

  • A. 修改进程状态为就绪态 一旦磁盘数据读完,所需资源已就绪,该进程就可以进入就绪态(Ready),等待调度器分配 CPU。✅
  • B. 降低进程优先级 优先级调整是调度策略行为,不是 I/O 完成的必然操作。❌
  • C. 给进程分配用户内存空间 用户内存通常在进程创建或加载程序时分配,不会因读磁盘完成而再次分配。❌
  • D. 增加进程时间片大小 时间片大小由调度策略设定,并不会因磁盘读写完成而改变。❌

问题27:

现有一个容量为10GB的磁盘分区,磁盘空间以簇 (Cluster) 为单位进行分配,簇的大小为4KB,若采用位图法管理该分区的空闲空间,即用一位 (bit) 标识一个簇是否被分配,则存放该位图所需簇的个数为( )。

A. 80 B. 320 C. 80K D. 320K

答案:A

解释:

  1. 磁盘总容量 = 10GB = 10 × 2³⁰ Bytes
  2. 每个簇大小 = 4KB = 2¹² Bytes
  3. 总簇数 = 10 × 2³⁰ / 2¹² = 10 × 2¹⁸ = 2ⁱ⁸ × 10 = 2,621,440 个簇
  4. 位图需要的空间 = 每簇1位 = 2,621,440 bits
  5. 换算为字节:2,621,440 / 8 = 327,680 Bytes
  6. 每个簇可存储数据 = 4KB = 4096 Bytes
  7. 位图占用的簇数 = 327,680 / 4096 = 80 个簇

故答案为 A.


问题28:

下列措施中,能加快虚实地址转换的是( )。

I. 增大快表 (TLB) 容量 II. 让页表常驻内存 III. 增大交换区 (swap)

A. 仅 I B. 仅 II C. 仅 I、II D. 仅 II、III

答案:C

解释:

  • I 正确:快表(TLB)是页表的高速缓存,容量变大可以减少TLB未命中的概率,从而减少访问主存页表的次数,加快地址转换速度。
  • II 正确:页表常驻内存避免了页表被换出到磁盘,从而在访问时不需要磁盘I/O,提升地址转换效率。
  • III 错误:交换区(swap)的大小影响内存页换出的空间,但与地址转换速度无直接关系。

故答案为 C.


29. 在一个文件被用户进程首次打开的过程中,操作系统需要做的是( )。

选项: A. 将文件内容读到内存中 B. 将文件控制块读到内存中 C. 修改文件控制块中的读写权限 D. 将文件的数据缓冲区首指针返回给用户进程

答案: B

解释: 当用户进程首次打开一个文件时,操作系统要完成以下关键步骤:

  • 文件查找:根据文件路径在文件系统中查找文件元数据(如 inode)。
  • 访问权限检查:确保用户对文件拥有所请求的访问权限(读/写/执行)。
  • 文件控制块(FCB)加载:将该文件的控制信息(如文件大小、访问时间、权限、数据块位置等)从磁盘加载到内存。
  • 文件描述符分配:为用户进程分配一个文件描述符,并关联内核中的打开文件表项。
  • A 错误:首次打开文件不会立即将文件内容读入内存,只有在真正执行 read() 操作时才进行数据加载。
  • B 正确:FCB 是描述文件属性的核心结构,必须加载入内存供后续访问使用。
  • C 错误:读写权限在文件创建或修改时设置,而不是在打开时修改。
  • D 错误:用户进程不会直接拿到内核的数据缓冲区指针,数据交换通过系统调用完成以确保安全性。

30. 在页式虚拟存储管理系统中,采用某些页面置换算法,会出现 Belady 异常现象。下列算法中,可能出现 Belady 异常现象的是( )。

I. LRU算法

II. FIFO算法

III. OPT算法

选项: A. 仅 II B. 仅 I、II C. 仅 I、III D. 仅 II、III

答案: A

解释: Belady 异常是指:分配的物理页框数量增加时,进程缺页次数反而上升,这是违反直觉的异常现象。

分析常见的三种页面置换算法:

  • I. LRU(Least Recently Used,最近最少使用)算法 ✅ 根据历史访问记录进行置换,遵循堆栈算法(Stack Algorithm),不会产生 Belady 异常。
  • II. FIFO(First-In First-Out,先进先出)算法 ❗根据页面进入内存的顺序置换页面,不考虑访问频率或时间。容易产生 Belady 异常,因为最早进入的页面不一定是最少使用的。
  • III. OPT(Optimal,最佳)算法 ✅ 理论上最优,使用“未来最长时间不会使用”的页面进行置换,不会出现 Belady 异常。

结论:只有 FIFO 算法可能出现 Belady 异常


31. 下列关于管道 (Pipe) 通信的叙述中,正确的是( )。

选项: A. 一个管道可实现双向数据传输 B. 管道的容量仅受磁盘容量大小限制 C. 进程对管道进行读操作和写操作都可能被阻塞 D. 一个管道只能有一个读进程或一个写进程对其操作

答案: C

解释:

  • A 错误普通管道(无名管道)是半双工通信,数据只能在一个方向上传输。如果需要双向通信,需要建立两个管道。
  • B 错误:管道是内存中的缓存区,其容量受操作系统内核设置的上限影响,与磁盘容量无关。
  • C 正确:管道是一种同步通信机制
    • 如果管道为空时,读操作会阻塞,直到有数据写入;
    • 如果管道已满时,写操作会阻塞,直到有数据被读出。
  • D 错误:一个管道可以有多个读进程和多个写进程,但同步由操作系统管理。例如,在 Linux 中多个进程可以继承同一个管道文件描述符来共享通信。

32. 下列选项中,属于多级页表优点的是( )。

选项: A. 加快地址变换速度 B. 减少缺页中断次数 C. 减少页表项所占字节数 D. 减少页表所占的连续内存空间

答案: D

解释:

  • A 错误多级页表会增加地址转换的查找步骤,因为每级页表都需要访问一次内存。虽然避免了整张大页表常驻内存,但访问速度上不占优势。
  • B 错误:多级页表的结构与缺页中断没有直接关系,缺页中断是由于访问的页不在物理内存中。
  • C 错误:多级页表总的页表项可能会更多,而每个页表项的大小是固定的,所以不会减少页表项占用的字节数。
  • D 正确多级页表的主要优势之一是节省连续内存空间。传统单级页表需要一个巨大的连续空间存放所有页表项,而多级页表通过分级结构,按需分配各级页表,只在使用时才分配子页表,因此显著降低了对大块连续内存的需求。

文件系统


46.(7分)

文件 F 由 200 条记录组成,记录从 1 开始编号。用户打开文件后,欲将内存中的一条记录插入文件 F 中,作为其第 30 条记录。请回答下列问题,并说明理由。


(1) 若文件系统采用连续分配方式,每个磁盘块存放一条记录,文件 F 存储区域前后均有足够的空闲磁盘空间,则完成上述插入操作最少需要访问多少次磁盘块?F 的文件控制块内容会发生哪些改变?

答案: 最少需要访问 59 次磁盘块。文件控制块(FCB)的 起始块号文件长度 将发生改变。

解释:

  • 连续分配方式下,所有记录按序存储在连续的磁盘块中,每条记录一个磁盘块。

  • 若将新记录插入为第 30 条记录,可以有两种移动策略:

    • 移动第 30~200 条记录(共 171 条)向后
    • 移动第 1~29 条记录(共 29 条)向前
  • 显然,第二种方式磁盘访问次数较少。

    步骤如下:

    1. 前移第 1~29 条记录到前面空闲的磁盘块,共 29 条记录,每条需读取 + 写入各 1 次 → 共访问 29 × 2 = 58 次磁盘块。
    2. 插入第 30 条新记录,需写入一次 → 再访问 1 次磁盘块。

    总共访问:58 + 1 = 59 次磁盘块。

  • 文件控制块(FCB)变化:

    • 起始块号发生改变(由于记录整体前移);
    • 文件长度增加(增加了一条记录);
    • 其他如修改时间等元数据也可能更新。

(2) 若文件系统采用链接分配方式,每个磁盘块存放一条记录和一个链接指针,则完成上述插入操作需要访问多少次磁盘块?若每个存储块大小为 1KB,其中 4B 存放链接指针,则该文件系统支持的文件最大长度是多少?

答案:

  • 需要访问 31 次磁盘块
  • 最大支持文件长度为 1020B × 2³² ≈ 4080 GB

解释:

  • 链接分配结构类似链表,插入操作只需修改链接指针。

  • 步骤如下:

    1. 顺着链接依次查找第 29 条记录所在磁盘块 → 需读取前 29 块 → 访问 29 次磁盘块
    2. 将新记录写入新分配的磁盘块,并设置其指针指向原第 30 条记录所在磁盘块 → 写 1 次
    3. 修改第 29 条记录所在磁盘块的链接指针,指向新插入记录所在的块 → 写 1 次

    总共访问:29 + 1 + 1 = 31 次磁盘块。

  • 最大支持文件长度:

    • 每块 1KB = 1024B,其中 4B 存放链接指针 → 可用于记录数据的空间是 1020B

    • 链接指针用 4 字节表示地址,最多可索引 2³² 个磁盘块

    • 所以最大支持记录数为 2³² 条,最大文件长度为:

      \[ 1020 \text{B} × 2^{32} = 4,378,053,222,400 \text{B} ≈ 4080 \text{GB} \]


✅ 本题总结:

  • (1) 连续分配方式访问磁盘块 59 次,需修改 FCB 的 起始块号长度
  • (2) 链接分配方式访问磁盘块 31 次,最大文件长度约 4080GB

PV操作

47.(8分)

系统中有多个生产者进程和多个消费者进程,共享一个能存放1000件产品的环形缓冲区(初始为空)。当缓冲区未满时,生产者进程可以放入其生产的一件产品,否则等待;当缓冲区未空时,消费者进程可以从缓冲区取走一件产品,否则等待。要求一个消费者进程从缓冲区连续取出10件产品后,其他消费者进程才可以取产品。

请使用信号量 P、V 操作(即 wait()signal())实现进程间的互斥与同步,要求写出完整过程,并说明所用信号量的含义和初值


解答:

一、分析:

本题是带特殊约束条件的生产者-消费者问题,约束在于:

每个消费者每次必须连续消费10件产品,而其他消费者必须等待这个消费者完成10件后才能继续消费。”

这就要求对消费者取产品的过程进行互斥批量处理。此外,由于是环形缓冲区,读写指针要循环使用。


二、设置信号量:

信号量名 初值 含义
empty 1000 表示当前缓冲区中的空位数量
full 0 表示当前缓冲区中已有的产品数量
mutex_p 1 控制多个生产者之间对缓冲区的互斥访问
mutex_c 1 控制消费者批量取10个产品时的互斥
buffer[1000] - 环形缓冲区,存放产品
front 0 消费者读取位置
rear 0 生产者写入位置

三、伪代码(C风格)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#define MAXSIZE 1000

semaphore empty = MAXSIZE; // 空槽数量
semaphore full = 0; // 产品数量
semaphore mutex_p = 1; // 生产者互斥
semaphore mutex_c = 1; // 消费者互斥(控制批量消费)

ElemType buffer[MAXSIZE]; // 环形缓冲区
int front = 0; // 消费者取产品位置
int rear = 0; // 生产者放产品位置

cobegin

// 生产者进程
Process Producer_i() {
while (true) {
生产一件产品 item;
P(empty); // 等待有空槽
P(mutex_p); // 进入生产临界区
buffer[rear] = item;
rear = (rear + 1) % MAXSIZE;
V(mutex_p); // 离开生产临界区
V(full); // 增加产品数
}
}

// 消费者进程
Process Consumer_i() {
while (true) {
P(mutex_c); // 批量消费互斥
for (int i = 0; i < 10; i++) {
P(full); // 等待有产品
// 不需要消费者之间互斥访问 front
ElemType item = buffer[front];
front = (front + 1) % MAXSIZE;
V(empty); // 增加空槽数
}
V(mutex_c); // 释放批量消费权限
消费10件产品;
}
}

coend

四、解释说明

  1. empty / full:
    • 控制缓冲区的空位和产品数,典型的生产者-消费者模型结构。
    • empty 初值为1000,因为开始时全空。
    • full 初值为0,因为开始没有产品。
  2. mutex_p:
    • 多个生产者可能同时尝试写入,因此使用互斥锁保护 rear 指针的操作。
  3. mutex_c:
    • 为了实现“一个消费者一次消费10件”*的特殊要求,需要一个互斥锁让*同一时刻只有一个消费者在进行10次连续消费。
  4. 环形缓冲区:
    • 使用 (index + 1) % MAXSIZE 实现循环读写。
  5. front/rear:
    • 不共享修改,front 只被消费者使用,rear 只被生产者使用,因此只需要分别互斥即可,不必生产者和消费者互斥。

✅ 结论总结:

  • 使用了5个信号量(empty, full, mutex_p, mutex_c)。
  • 成功实现了互斥写入、批量读取、缓冲区空满控制
  • 满足题目要求的“一个消费者必须连续取10件产品,其他消费者等待”的特殊同步逻辑。