MST
星途 面试题库

面试题:并发与同步:信号量在多线程协作中的应用

假设有一个生产者 - 消费者模型,生产者线程不断生成数据并放入缓冲区,消费者线程从缓冲区取出数据进行处理。请使用信号量来实现这个模型的同步机制,简要描述信号量的设计思路以及代码实现框架(可使用伪代码)。
33.2万 热度难度
操作系统并发与同步

知识考点

AI 面试

面试题答案

一键面试

信号量设计思路

  1. 空缓冲区信号量:用于表示缓冲区中可用的空间,初始值为缓冲区的大小。当生产者要向缓冲区写入数据时,需要先获取这个信号量,如果信号量的值大于0,则表示有可用空间,生产者可以写入数据,同时信号量的值减1。
  2. 满缓冲区信号量:用于表示缓冲区中已有的数据,初始值为0。当消费者要从缓冲区读取数据时,需要先获取这个信号量,如果信号量的值大于0,则表示有数据可读,消费者可以读取数据,同时信号量的值减1。
  3. 互斥信号量:用于保护对缓冲区的访问,确保同一时间只有一个线程可以访问缓冲区,初始值为1。

代码实现框架(伪代码)

// 定义缓冲区大小
const int bufferSize = 10; 
// 空缓冲区信号量,初始值为缓冲区大小
Semaphore empty(bufferSize); 
// 满缓冲区信号量,初始值为0
Semaphore full(0); 
// 互斥信号量,初始值为1
Semaphore mutex(1); 

// 缓冲区数组
int buffer[bufferSize]; 
// 缓冲区索引
int in = 0; 
int out = 0; 

// 生产者线程函数
void Producer() {
    while (true) {
        // 生成数据
        int data = generateData(); 
        // 获取空缓冲区信号量
        empty.wait(); 
        // 获取互斥信号量
        mutex.wait(); 
        // 向缓冲区写入数据
        buffer[in] = data; 
        in = (in + 1) % bufferSize; 
        // 释放互斥信号量
        mutex.signal(); 
        // 释放满缓冲区信号量
        full.signal(); 
    }
}

// 消费者线程函数
void Consumer() {
    while (true) {
        // 获取满缓冲区信号量
        full.wait(); 
        // 获取互斥信号量
        mutex.wait(); 
        // 从缓冲区读取数据
        int data = buffer[out]; 
        out = (out + 1) % bufferSize; 
        // 释放互斥信号量
        mutex.signal(); 
        // 释放空缓冲区信号量
        empty.signal(); 
        // 处理数据
        processData(data); 
    }
}