Skip to content

408

操作系统

信号量机制


一、定位信息

  • 所属圈层:核心层
  • 前置知识:了解同步与互斥的基本概念(OS-02-09),了解软件/硬件互斥实现(OS-02-10)
  • 知识网络位置:信号量是实现同步与互斥的最核心工具,是经典同步问题(OS-02-12)和管程(OS-02-13)的基础
  • 考点热度等级H级(高频重点)——信号量的操作和应用几乎每年必考,是408操作系统部分的核心考点

二、知识点讲解

2.1 信号量的概念

信号量(Semaphore)是由Dijkstra提出的同步工具,通过两个原子操作 P(wait/申请)和 V(signal/释放)来实现进程间的同步与互斥。

2.2 整型信号量

c
int S;  // 信号量,表示资源数量

P(S):   // 申请资源
    while (S <= 0);  // 忙等待
    S = S - 1;

V(S):   // 释放资源
    S = S + 1;

问题:不满足"让权等待"(忙等待)。

2.3 记录型信号量(重点)

c
typedef struct {
    int value;           // 资源数量
    struct process *L;   // 等待队列
} semaphore;

P(S):   // 申请资源
    S.value--;
    if (S.value < 0) {
        // 没有资源了,将当前进程加入等待队列
        block(S.L);  // 进程阻塞
    }

V(S):   // 释放资源
    S.value++;
    if (S.value <= 0) {
        // 有进程在等待,唤醒一个
        wakeup(S.L);  // 从等待队列唤醒一个进程
    }

关键理解

  • S.value > 0:还有可用资源
  • S.value = 0:资源用完,但没有进程在等待
  • S.value < 0:资源用完,且有 |S.value| 个进程在等待

2.4 信号量实现互斥

c
semaphore mutex = 1;  // 互斥信号量,初始值为1

// 进程Pi
P(mutex);       // 进入临界区前申请
// 临界区
V(mutex);       // 退出临界区后释放

2.5 信号量实现同步

c
semaphore S = 0;  // 同步信号量,初始值为0

// 进程P1(先执行的操作)
// ...操作A...
V(S);              // 通知P2:A已完成

// 进程P2(后执行的操作)
P(S);              // 等待P1完成A
// ...操作B...

核心思想:P操作"等通知",V操作"发通知"。

2.6 互斥信号量 vs 同步信号量

维度互斥信号量同步信号量
初始值10(通常)
目的保护临界区(互斥)协调执行顺序(同步)
P/V配对同一进程中P和V配对不同进程中P和V配对
P操作含义申请进入临界区等待前置条件满足
V操作含义释放临界区通知条件已满足

三、记忆与理解辅助

  1. 口诀:"P申请V释放,P等V通知"
  2. 信号量值的含义:正数=有资源,零=刚好用完,负数=有进程在等待(绝对值=等待进程数)
  3. 互斥信号量初值=1,同步信号量初值=0——这是最常考的初始值设置
  4. P/V操作必须成对出现:有P必有V,否则可能导致死锁或永远阻塞

四、例题与精解

例题1(基础巩固)

题目:设信号量S的初始值为3,经过5次P操作和2次V操作后,S的值为( )

A. 0 B. -1 C. 1 D. -2

命题意图:考查信号量值的计算。

精解

  1. 审题分析:初始值3,5次P操作(每次-1),2次V操作(每次+1)
  2. 解题思路:S = 初始值 - P操作次数 + V操作次数
  3. 完整步骤
    • S = 3 - 5 + 2 = 0
    • 但需要注意:当S值降到0以下时,后续P操作会导致进程阻塞
    • 前3次P操作:S = 3→2→1→0(进程不阻塞)
    • 第4次P操作:S = 0→-1(第4个进程阻塞)
    • 第5次P操作:S = -1→-2(第5个进程阻塞)
    • 2次V操作:S = -2→-1→0(每次V唤醒一个等待进程)
    • 最终S = 0
  4. 方法反思:S的绝对值在负数时表示等待的进程数。V操作会唤醒等待进程

答案:A

例题2(中等提升)

题目:用信号量实现"进程P1的语句S1执行完后,P2才能执行语句S2"的同步关系,正确的代码是( )

A. 信号量sem=1; P1: S1; V(sem); P2: P(sem); S2; B. 信号量sem=0; P1: S1; V(sem); P2: P(sem); S2; C. 信号量sem=0; P1: P(sem); S1; V(sem); P2: S2; D. 信号量sem=1; P1: P(sem); S1; V(sem); P2: S2;

命题意图:考查信号量实现同步的方法。

精解

  1. 审题分析:要求S1先于S2执行,即P2必须等待P1完成S1
  2. 解题思路:同步信号量初始值为0,P1执行完后V(sem)通知P2,P2先P(sem)等待
  3. 完整步骤
    • A选项:sem=1时,P2的P(sem)可能在S1执行前就通过了(因为初始值为1,P操作不会阻塞),不满足同步
    • B选项:sem=0时,P2的P(sem)会阻塞,直到P1执行S1后V(sem)将其唤醒。正确
    • C选项:P1先P(sem)会阻塞(sem=0),导致死锁
    • D选项:sem=1时,P1的P(sem)不阻塞直接执行S1,但P2没有P操作,不能保证等待S1完成
  4. 方法反思:同步信号量初始值=0,"前V后P"——先执行的进程最后V,后执行的进程先P

答案:B


五、考情分析

  • 考查频次:近5年每年必考
  • 常见题型:选择题 + 综合题(用信号量解决同步问题)
  • 分值占比:选择题2分,综合题5–10分
  • 命题趋势:信号量的初始值设置、P/V操作的执行结果计算是基础题;用信号量解决经典同步问题是综合题

六、易错点提醒

  1. 错误表现:互斥信号量和同步信号量的初始值搞混 错误原因:两者都用信号量,但初始值不同 正确理解:互斥信号量初值=1(表示一个临界区),同步信号量初值=0(表示还没有前置条件)

  2. 错误表现:P/V操作不在同一进程中配对 错误原因:将互斥的P/V配对方式套用到同步场景 正确理解:互斥时P/V在同一进程中配对(进入前P,退出后V);同步时P/V在不同进程中(先执行的进程V,后执行的进程P)

  3. 错误表现:认为V操作不可能导致进程阻塞 错误原因:只记住了"V释放资源" 正确理解:V操作本身不会阻塞,但V操作后如果有进程被唤醒,当前进程可能被调度器切换(不过这不是V操作导致的阻塞)

  4. 错误表现:忘记信号量的P/V操作是原子操作 错误原因:将P/V当作普通函数 正确理解:P和V是原子操作,执行过程中不可被中断


七、来源标注

  • 依据2026考研统考408大纲
  • 依据《计算机操作系统》(汤小丹/汤子瀛版)第2章
  • 依据《操作系统概念》(Silberschatz版)第6章
  • 依据王道考研408操作系统辅导讲义

考研全科复习资料 - 基于2026考研统考大纲