MST
星途 面试题库

面试题:并发与同步之中等难度:生产者 - 消费者问题

在经典的生产者 - 消费者场景中,使用信号量机制来实现生产者和消费者的同步。假设生产者生产数据放入一个共享缓冲区,消费者从共享缓冲区取出数据。请描述信号量的种类、初值设置以及生产者和消费者的操作逻辑,并用伪代码实现。
17.6万 热度难度
操作系统并发与同步

知识考点

AI 面试

面试题答案

一键面试
  1. 信号量种类及初值设置
    • empty:表示共享缓冲区中的空闲位置数量,初值为共享缓冲区的大小 n
    • full:表示共享缓冲区中已占用的位置数量,初值为 0。
    • mutex:用于保护共享缓冲区的互斥访问,初值为 1。
  2. 生产者操作逻辑
    • 等待 empty 信号量,获取共享缓冲区中的空闲位置。
    • 等待 mutex 信号量,进入临界区,保护共享缓冲区。
    • 将数据放入共享缓冲区。
    • 释放 mutex 信号量,离开临界区。
    • 释放 full 信号量,表示共享缓冲区有新数据可供消费。
  3. 消费者操作逻辑
    • 等待 full 信号量,获取共享缓冲区中的数据。
    • 等待 mutex 信号量,进入临界区,保护共享缓冲区。
    • 从共享缓冲区取出数据。
    • 释放 mutex 信号量,离开临界区。
    • 释放 empty 信号量,表示共享缓冲区有空闲位置。
  4. 伪代码实现
// 定义共享缓冲区大小
const int n = 10; 
// 定义信号量
Semaphore empty(n); 
Semaphore full(0); 
Semaphore mutex(1); 

// 生产者线程
void producer() {
    while (true) {
        // 生产数据
        int data = produceData(); 
        // 等待空闲位置
        empty.wait(); 
        // 进入临界区
        mutex.wait(); 
        // 将数据放入共享缓冲区
        putDataToBuffer(data); 
        // 离开临界区
        mutex.signal(); 
        // 通知缓冲区有新数据
        full.signal(); 
    }
}

// 消费者线程
void consumer() {
    while (true) {
        // 等待有数据
        full.wait(); 
        // 进入临界区
        mutex.wait(); 
        // 从共享缓冲区取出数据
        int data = getDataFromBuffer(); 
        // 离开临界区
        mutex.signal(); 
        // 通知缓冲区有空闲位置
        empty.signal(); 
        // 消费数据
        consumeData(data); 
    }
}