操作系统 生产者 - 消费者问题

问题描述

生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。

记录型信号量

思路

  • 假定在生产者和消费者之间的公用缓冲池中具有n个缓冲区,这时可利用互斥信号量mutex实现诸进程对缓冲池的互斥使用;利用信号量empty和full分别表示缓冲池中空缓冲区和满缓冲区的数量。又假定这些生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池中取走一个消息。
  • 使用互斥信号量mutex,实现对公用缓冲池的互斥使用
  • 使用信号量empty和full代替原来的count计数,同时实现线程的同步机制
  • 利用数组buffer模拟具有n个缓冲区的缓冲池,指针in,out表示该放入缓冲区的位置,于该取走缓冲区的位置,使用 ( in / out = (in / out + 1) % n)实现循环缓冲区

在这里插入图片描述

代码实现

int in = 0, out = 0;  //位置记录
item buffer[n];  //缓冲池
semaphore mutex = 1;  //互斥信号量
semaphore empty = n, full = 0;  //同步信号量

void producer(){
	do{
		produce an item nextp;  //产生商品nextp
		……
		wait(empty);  //wait的顺序不能变换
		wait(mutex);
		buffer[in] = nextp;
		in = (in + 1) % n;
		signal(mutex);
		signal(full);
	}while(TRUE);
}

void consumer(){
	do{
		wait(full);  //wait的顺序不能变换
		wait(mutex);
		nextc = buffer[out];
		out = (out + 1) % n;
		signal(mutex);
		signal(empty);
		consumer the item in nextc;
		……
	}while(TRUE);
}

void main(){
	cobegin;  //同时开始
	producer();
	consumer();
	coend;
}

注意点

  • 互斥型信号量mutex的wait()与signal()操作一定要成对出现
  • 资源信号量empty与full的wait()与signal操作虽然不在同一进程中,但是为了实现同步,同时避免死锁一定也要对应出现
  • 一个进程中的wait()操作的次序不能颠倒,一定是先对资源信号量再对互斥信号量使用wait()

AND信号量

思路

  • 因为同时需要生产者与消费者都同时需要两个信号量的控制,故引入AND信号量
  • 使用Swait(empty,mutex)代替wait(empty),wait(mutex)
  • 使用Ssignal(mutex, full)代替signal(mutex),signal(full)
  • 同理Swait(full,mutex),Ssignal(mutex, empty)

代码实现

int in = 0, out = 0;  //位置记录
item buffer[n];  //缓冲池
semaphore mutex = 1;  //互斥信号量
semaphore empty = n, full = 0;  //同步信号量

void producer(){
	do{
		produce an item nextp;
		……
		Swait(empty, mutex);
		buffer[in] = nextp;
		in = (in + 1) % n;
		Ssignal(mutex, full);
	}while(TRUE);
}

void consumer(){
	do{
		Swait(full, mutex);
		nextc = buffer[out];
		out = (out + 1) % n;
		Ssignal(mutex, empty);
		consumer the item in nextc;
		……
	}while(TRUE);
}

void main(){
	cobegin;  //同时开始
	producer();
	consumer();
	coend;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TYUT ljk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值