📜  使用信号量的生产者消费者问题 |设置 1

📅  最后修改于: 2021-09-28 10:08:38             🧑  作者: Mango

先决条件 –操作系统中的信号量,进程间通信
生产者消费者问题是一个经典的同步问题。我们可以通过使用信号量来解决这个问题。

信号量S 是一个整数变量,只能通过两个标准操作访问:wait() 和 signal()。
wait() 操作将 semaphore 的值减 1,signal() 操作将其值加 1。

wait(S){
while(S<=0);   // busy waiting
S--;
}

signal(S){
S++;
}

信号量有两种类型:

  1. 二进制信号量——这类似于互斥锁,但不是一回事。它只能有 0 和 1 两个值。它的值被初始化为 1。它用于实现多进程临界区问题的解决方案。
  2. 计数信号量——它的值可以跨越一个不受限制的域。它用于控制对具有多个实例的资源的访问。

问题陈述 –我们有一个固定大小的缓冲区。生产者可以生产一个项目并可以放置在缓冲区中。消费者可以挑选物品并消费它们。我们需要确保当生产者在缓冲区中放置一个项目时,同时消费者不应消费任何项目。在这个问题中,缓冲区是关键部分。

为了解决这个问题,我们需要两个计数信号量——Full 和 Empty。 “Full”在任何给定时间跟踪缓冲区中的项目数量,“Empty”跟踪未占用插槽的数量。

信号量的初始化——
互斥量 = 1
Full = 0 // 最初,所有插槽都是空的。因此完整的插槽为 0
Empty = n // 所有插槽最初都是空的

生产者解决方案 –

do{

//produce an item

wait(empty);
wait(mutex);

//place in buffer

signal(mutex);
signal(full);

}while(true)

当生产者生产一个物品时,“空”的值减 1,因为现在将填充一个插槽。互斥量的值也被减少以防止消费者访问缓冲区。现在,生产者已经放置了该项目,因此“full”的值增加了 1。 mutex 的值也增加了 1,因为生产者的任务已经完成,消费者可以访问缓冲区。

消费者解决方案 –

do{

wait(full);
wait(mutex);

// remove item from buffer

signal(mutex);
signal(empty);

// consumes item

}while(true)

由于消费者正在从缓冲区中删除一个项目,因此“full”的值减1,并且mutex的值也减少,因此此时生产者无法访问缓冲区。现在,消费者已经消费了该项目,因此将“空”的值增加了 1。互斥锁的值也增加了,以便生产者现在可以访问缓冲区。

见实现——在Java使用信号量的生产者-消费者解决方案| 2套