一、问题描述
系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。(注:这里的“产品”理解为某种数据)
特点:
生产者、消费者共享一个初始为空、大小为n的缓冲区。
只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。
只有缓冲区不空时,消费者才能从中取出产品,否则必须等待。
缓冲区是临界资源,各进程必须互斥地访问。
缓冲区满时,生产者必须等待,缓冲区空时,消费者必须等待
分析同步互斥关系:
缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。
同步关系——缓冲区满时,生产者必须等待消费者取走产品
只有缓冲区不空时,消费者才能从中取出产品,否则必须等待。
同步关系——缓冲区空时,消费者必须等待生产者取走产品
缓冲区是临界资源,各进程必须互斥地访问。
互斥关系
信号量机制实现:
互斥:设置初值为1的互斥信号量
同步:设置初值为0的同步信号量(实现一前一后)
//互斥信号量,实现对缓冲区的互斥访问 semaphore mutex = 1; //同步信号量,表示空闲缓冲区的数量 semaphore full = n ; //同步信号量,表示产品的数量,也即非空缓冲区的数量 semaphore empty = 0;
二、实现
//生产者 producer () { while(1) { 生产一个产品; p(empty);//生产一个产品——消耗一个空闲缓冲区 p(mutex);//要操作缓冲区,必须先上锁 把产品放入缓冲区; v(mutex);//操作完之后,要解锁 v(full);//增加一个产品 } } //消费者 consumer () { while(1) { p(full);//消耗一个产品 p(mutex);//加锁 //从缓冲区取出一个产品 v(mutex);//解锁 v(empty);//增加一个空闲缓冲区 } }
实现互斥:在同一进程中进行一对pv操作
实现两进程同步:是在其中一个进程执行p,另一个进程中执行v
实现互斥的p操作一定要在实现同步的p操作之后,防止死锁。就是加锁只加在你要操作的代码区之间
v操作不会导致进程阻塞,因此v操作顺序可以交换