进程的互斥控制_消费者生产者经典问题

题目:
假定在生产者和消费者之间的公用缓冲池中具有n个缓冲区,消费者不能同时取一个缓冲区的产品,生产者不能同时向同一个缓冲区放入产品。只有缓冲区中有产品时,消费者才可以取产品,只有缓冲区有空时,生产者才可以放入产品。消费者与生产者也不能同时对同一个缓冲区进行操作。
代码:

信号量的设置:
名称			初值		含义
empty			n		缓冲池中的空闲缓冲区个数
produce			0		缓冲池中产品的个数
mutex			1		同时对缓冲区的操作互斥控制

void producer(){
while(1){
	wait(empty);		//申请空位
	wait(mutex);
	//放入产品操作
	signal(mutex);
	signal(produce);		//放置产品
	}
}

void consumer(){
while(1){
	wait(produce);		//申请产品
	wait(mutex);
	//取出产品操作
	signal(mutex);
	signal(empty);		//释放空位
	}
}

int main(){
	consumer.start();
	producer.start();
}

分析:
问题相当简单,需要互斥的操作有两个:
①.放入产品操作,要满足:放时不能取,无时不能取
②.取出产品操作,要满足:拿时不能放,满时不能放
放时不能取和拿时不能放通过两个进程对同一个信号量mutex进行申请即可实现
无时不能取则让取方(消费者)对produce信号量进行申请,无则阻塞
满时不能放则让放方(生产者)对empty信号量进行申请,无时阻塞

更进一步的

在此问题上增加要求:消费者要一口气拿10个产品才退出,在此期间其他消费者不能拿取
那么,分析一下,只需要将拿取一个产品的操作当做一个整体,对这个整体操作再进行互斥控制,在拿满十次之前不让其他进程进入拿取操作即可.
消费者代码如下:

新增信号量:
keep	1		同时可进行取操作的消费者个数
void consumer(){
while(1){
	wait(keep)
	for(int i=0;i<10;i++)
	{
		wait(produce);		//申请产品
		wait(mutex);
		//取出产品操作
		signal(mutex);
		signal(empty);		//释放空位
	}
	signal(keep)
	}
}

这样,当其他消费者试图取操作时,都会对keep信号量进行询问,若有人没取完10个,则会被阻塞在这里,等待signal(keep)的时候被唤醒.

猜你喜欢

转载自blog.csdn.net/qq_39560579/article/details/82858678