Skip to content

生产者-消费者问题

考情分析

生产者-消费者问题是 408 真题中出现频率最高的同步问题,大题几乎必考 PV 操作的变形。属于 🔥🔥🔥 绝对核心。

快递员把包裹放进快递柜,取件人从柜子里取走。柜子满了快递员得等,柜子空了取件人得等,而且两人不能同时对同一个格子操作——这就是生产者-消费者问题的日常版本。

问题描述

  • 一组生产者进程向缓冲区中放入数据
  • 一组消费者进程从缓冲区中取出数据
  • 缓冲区大小为 N

需要满足的同步/互斥关系:

关系说明
互斥生产者和消费者不能同时访问缓冲区
同步缓冲区满时生产者等待;缓冲区空时消费者等待

信号量设计

semaphore mutex = 1;     // 互斥信号量:保护缓冲区的互斥访问
semaphore empty = N;     // 同步信号量:空闲缓冲区数量
semaphore full  = 0;     // 同步信号量:已占用缓冲区数量

完整解答

// 生产者进程
producer() {
    while (true) {
        item = produce();    // 生产一个产品
        P(empty);            // ① 申请一个空缓冲区
        P(mutex);            // ② 进入临界区
        put(item);           // 放入缓冲区
        V(mutex);            // ③ 离开临界区
        V(full);             // ④ 增加一个满缓冲区
    }
}

// 消费者进程
consumer() {
    while (true) {
        P(full);             // ① 申请一个满缓冲区
        P(mutex);            // ② 进入临界区
        item = get();        // 从缓冲区取出
        V(mutex);            // ③ 离开临界区
        V(empty);            // ④ 增加一个空缓冲区
        consume(item);       // 消费产品
    }
}

P 操作顺序至关重要

P 操作顺序不能颠倒

如果将生产者的 P 操作顺序改为先 P(mutex)P(empty)

// 错误写法!
producer() {
    P(mutex);    // 先获取锁
    P(empty);    // 再申请空缓冲区 → 如果缓冲区满,阻塞在这里
    ...          // 但此时 mutex 没有释放!
}

缓冲区满时,生产者持有 mutex 但阻塞在 P(empty),消费者想消费但获取不到 mutex → 死锁

规则:实现互斥的 P 操作一定要在实现同步的 P 操作之后。V 操作的顺序无所谓。

交互可视化

加载可视化中...

变形题

多生产者多消费者问题

多种类型的生产者和消费者共享缓冲区:

示例:桌上有一个盘子(缓冲区大小=1),父亲放苹果,母亲放橘子,女儿吃苹果,儿子吃橘子。

semaphore plate = 1;      // 盘子是否为空
semaphore apple = 0;      // 盘中苹果数
semaphore orange = 0;     // 盘中橘子数

father() {               daughter() {
    P(plate);                 P(apple);
    放苹果;                    取苹果;
    V(apple);                 V(plate);
}                        }

mother() {               son() {
    P(plate);                 P(orange);
    放橘子;                    取橘子;
    V(orange);                V(plate);
}                        }

注意:这里缓冲区大小=1,不需要额外的 mutex(因为 plate 本身就起到了互斥作用)。

吸烟者问题

类似的多资源协作问题,也是经典考题。

考研高频考点

  • 🔥🔥🔥 标准的生产者-消费者 PV 操作写法
  • 🔥🔥🔥 P 操作顺序不能颠倒(先同步后互斥)
  • 🔥🔥🔥 信号量初值的确定(empty=N, full=0, mutex=1)
  • 🔥🔥 V 操作顺序可以任意
  • 🔥🔥 各种变形问题的信号量设计

生产者-消费者处理的是"一方生产、一方消费"的场景。如果多方同时读、偶尔有人写呢?下一篇看读者-写者问题。

真题练习

相关真题(5题)

2025Q45综合题8分

综合题:多资源多步骤的同步互斥问题(铁锹互斥+工序同步+坑数限制)

2015Q45综合题9分

综合题:双信箱辩论的生产者-消费者同步问题

2014Q47综合题8分

综合题:环形缓冲区的生产者-消费者问题,消费者需连续取10件

2011Q45综合题8分

综合题:银行叫号系统的同步互斥问题(座位限制+取号互斥+服务同步)

2009Q45综合题7分

综合题:一个生产者+两种消费者共享缓冲区的同步互斥问题