MST

星途 面试题库

面试题:进程管理之信号量基础应用

请阐述信号量在进程同步与互斥中的基本原理,并举例说明如何使用信号量解决生产者 - 消费者问题,假设生产者和消费者进程都在一个多进程系统中,且共享一个有限大小的缓冲区。
30.8万 热度难度
操作系统进程管理

知识考点

AI 面试

面试题答案

一键面试

信号量在进程同步与互斥中的基本原理

信号量(Semaphore)是一个整型变量,它通过一个计数器来控制对共享资源的访问。其基本原理如下:

  1. 互斥:当信号量的初始值设为1时,它可以用于实现互斥。此时信号量起到一个二元信号量(即0或1)的作用。进程在进入临界区(共享资源访问区域)前,先尝试获取信号量(将计数器减1),如果计数器值变为0,表示获取成功,可以进入临界区;若为负数(因为初始值为1,这里实际只能是 -1),表示已有其他进程占用,当前进程需等待。当进程离开临界区时,释放信号量(将计数器加1)。
  2. 同步:信号量初始值可设为其他正整数,用于表示可用资源的数量。进程需要使用资源时,尝试获取信号量(计数器减1),若计数器值大于等于0,表示有可用资源,可继续执行;若小于0,表示资源不足,进程进入等待队列。当进程使用完资源后,释放信号量(计数器加1),唤醒等待队列中的进程。

使用信号量解决生产者 - 消费者问题

假设共享缓冲区大小为 n,我们需要使用三个信号量:

  1. empty:表示缓冲区中的空闲槽位,初始值为 n
  2. full:表示缓冲区中的已占用槽位,初始值为 0。
  3. mutex:用于互斥访问缓冲区,初始值为 1。

以下是用伪代码示例:

生产者进程

while (true) {
    produce_item(); // 生产一个产品
    wait(empty);    // 等待缓冲区有空闲槽位
    wait(mutex);    // 进入临界区
    add_item_to_buffer(); // 将产品放入缓冲区
    signal(mutex);  // 离开临界区
    signal(full);   // 通知缓冲区有新数据
}

消费者进程

while (true) {
    wait(full);     // 等待缓冲区有数据
    wait(mutex);    // 进入临界区
    remove_item_from_buffer(); // 从缓冲区取出产品
    signal(mutex);  // 离开临界区
    signal(empty);  // 通知缓冲区有空闲槽位
    consume_item(); // 消费产品
}

在上述代码中,生产者先等待 empty 信号量(表示缓冲区有空闲空间),获取后进入临界区将产品放入缓冲区,然后释放 mutex 信号量(离开临界区)并发送 full 信号量(表示缓冲区有新数据)。消费者则先等待 full 信号量(表示缓冲区有数据),获取后进入临界区取出产品,然后释放 mutex 信号量(离开临界区)并发送 empty 信号量(表示缓冲区有空闲空间)。这样通过信号量的协调,实现了生产者和消费者之间的同步与对共享缓冲区的互斥访问。