同步与互斥-操作系统

生产者–消费者问题

用到的概念:

  • 信号量 (Semaphore) —— 用来同步和互斥,控制共享资源。
  • P()V() 操作 —— 分别是获取和释放信号量。
  • 互斥信号量 (mutex) —— 用来保护临界区。
  • 同步信号量 (emptyfull) —— 用来控制生产者和消费者之间的同步。

信号量

标准操作系统教材(如《操作系统概念》Silberschatz)里,经典的「生产者-消费者问题」,用的信号量名字就是:

  • empty —— 空槽位数
  • full —— 满槽位数
  • mutex —— 缓冲区互斥锁

PV操作

这是标准的P/V操作,也叫信号量操作,源于操作系统理论。

  • P(s):对信号量s执行减1操作,如果s <= 0,调用P()的进程就阻塞等待。
  • V(s):对信号量s执行加1操作,如果有因为这个信号量而阻塞的进程,会唤醒其中一个。

P(empty)

  • 意义:检查是否还有空闲槽。
  • 含义:empty是一个计数信号量,值表示空闲槽位数。
  • empty > 0:能放入产品,值减1。
  • empty == 0:没有空闲槽,调用P(empty)的进程就阻塞,直到有消费者消费掉一件产品。

P(mutex)

  • 意义:进入临界区。
  • 含义:mutex是一个互斥信号量,值是0或1。
  • mutex == 1:允许进入临界区,值减为0。
  • mutex == 0:表示已经有别的进程进入,调用P(mutex)的进程阻塞。

V(mutex)

  • 意思:释放互斥锁
  • 执行完临界区后,调用V(mutex)让其他被阻塞的进程有机会进入。
  • 简而言之:mutex值 +1,表示“我已经退出临界区,你们可以进来了。”

V(full)

  • 意思:增加满槽数
  • 执行完放入操作后,调用V(full)让因为P(full)而阻塞的消费者解锁。
  • 简而言之:让消费者知道,“现在有一件产品可取了!”

例题

系统中有多个生产者进程和多个消费者进程,共享一个能存放1000件产品的环形缓冲区(初始为空)。缓冲区未满时,生产者进程可以放入其生产的一件产品,否则等待;缓冲区未空时,消费者进程可从缓冲区取走一件产品,否则等待。要求一个消费者进程从缓冲区连续取出10件产品后,其他消费者进程才可以取产品。请使用信号量PV操作实现进程间的互斥与同步,要求写出完整的过程,并说明所用信号量的含义和初值

信号量定义及初值

// 信号量及共享变量
semaphore empty = 1000;           // 空闲槽位数,初值为1000
semaphore full = 0;              // 满槽位数,初值为0
semaphore mutex = 1;              // 缓冲区互斥锁,初值为1
semaphore consumer_turn = 1;      // 控制消费者连续消费,初值为1
// 共享变量
int count_10 = 0;                // 当前连续消费数

🟩 生产者代码

while (1) {
    item = produce();
    P(empty);           // 检查是否还有空位
    P(mutex);           // 获取互斥锁
    put_item(item);      // 向缓冲区放入产品
    V(mutex);           // 释放互斥锁
    V(full);            // 增加满槽数,通知消费者
}

🟦 消费者代码

while (1) {
    P(consumer_turn);           // 获取消费权
    for (int i = 0; i < 10; i++) {
        P(full);                // 检查是否有产品
        P(mutex);               // 获取互斥锁
        item = remove_item();    // 从缓冲区取出产品
        V(mutex);               // 释放互斥锁
        V(empty);               // 增加空槽数,通知生产者
        consume(item);
    }
    V(consumer_turn);           // 完成10次消费,释放消费权
}

具体的应用

在实际编程里,它出现在:

  • 线程池、协程池
  • 消息队列、任务队列
  • 网络IO、日志收集器
  • 缓冲区管理
posted @ 2025-06-22 23:36  海浪博客  阅读(19)  评论(0)    收藏  举报