生产者-消费者(producer-consumer)问题,也称作有界缓冲区(bounded-buffer)问题,两个进程共享一个公共的固定大小的 缓冲区。其中一个是生产者,用于将消息放入缓冲区;另外一个是消费者,用于从缓冲区中取出消息。问题出现在当缓冲区已经满了,而此时生产者还想向其中放入 一个新的数据项的情形,其解决方法是让生产者此时进行休眠,等待消费者从缓冲区中取走了一个或者多个数据后再去唤醒它。同样地,当缓冲区已经空了,而消费 者还想去取消息,此时也可以让消费者进行休眠,等待生产者放入一个或者多个数据时再唤醒它。
听起来好像蛮对的,无懈可击似的,但其实在实 现时会有一个竞争条件存在的。为了跟踪缓冲区中的消息数目,需要一个变量 count。如果缓冲区最多存放 N 个消息,则生产者的代码会首先检查 count 是否达到 N,如果是,则生产者休眠;否则,生产者向缓冲区中放入一个消息,并增加 count 的值。
消费者的代码也与此类似,首先检测 count 是否为 0,如果是,则休眠;否则,从缓冲区中取出消息并递减 count 的值。同时,每个进程也需要检查是否需要唤醒另一个进程。代码可能如下:
// 缓冲区大小
#define N 100
int count = 0; // 跟踪缓冲区的记录数
/* 生产者进程 */
void procedure(void)
{
int item; // 缓冲区中的数据项
while(true) // 无限循环
{
item = produce_item(); // 产生下一个数据项
if (count == N) // 如果缓冲区满了,进行休眠
{
sleep();
}
insert_item(item); // 将新数据项放入缓冲区
count = count + 1; // 计数器加 1
if (count == 1) // 表明插入之前为空,
{ // 消费者等待
wakeup(consumer); // 唤醒消费者
}
}
}
/* 消费者进程 */
生产者-消费者(producer-consumer)问题(二)
于 2011-05-21 16:35:00 首次发布