生产者消费者问题
系统中有一组生产者进程和消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品使用
(产品为某种数据)
生产者消费者共享一个初始为空 大小为n的缓冲区
只有缓冲区没满的时候 生产者才能将产品放入缓冲区,否则必须等待
(同步关系 缓冲区满的时候,生产者要等待消费者取走产品)
只有缓冲区不空的时候 消费者才能从缓冲区中取出产品否则必须等待
(同步关系 缓冲区空的时候 消费者必须等待生产者放入产品)
缓冲区是临界资源 所以各进程必须互斥的访问
我们可以使用P,V操作实现生产者和消费者进程的功能
由之前的学习我们知道 信号量机制可实现互斥,同步,对一类系统资源的申请和释放
互斥 设置初值为1的互斥信号量
**同步 设置初值为0的同步信号量 实现一前一后 **
设置一个信号量 初值为资源的数量(本质上也是同步问题 若无空闲资源,则申请资源的进程需要等待其他进程释放资源之后才能执行)
然后我们用代码来实现一下
在实现之前 我们再来捋一下
生产者工作的前提:消费者没有工作 空闲缓冲区数量大于0
消费者工作的前提:生产者没有工作 产品剩余数量大于0
满足上边两条即可
semaphore mutex = 1;//互斥信号量 实现对缓冲区的互斥访问
semaphore empty = n;//同步信号量 表示空闲缓冲区的数量
semaphore full = 0;//同步信号量 表示产品数量 也是非空缓冲区的数量
producer(){
//生产者
while(1){
生产一个产品
P(empty);
P(mutex);
把产品放入缓存区
V(mutex);
V(full);
}
}
consumer(){
//消费者
while(1){
P(full);
P(mutex);
从缓冲区取出一个产品
V(mutex);
V(empty);
使用产品
}
}
特别注意 其中的P语句顺序不能颠倒顺序 否则会出问题 但是V语句可以交换顺序
生产者等待消费者释放空闲缓冲区,消费者等待生产者释放临界区
生产者和消费者循环等待对方唤醒自己 出现死锁
实现互斥的P操作一定要在实现同步的P之后
生产者消费者问题是一个互斥同步的综合问题
**实现一前一后 需要前V后P **
最后还是要强调一点 就是:实现互斥和实现同步的先后顺序
多生产者多消费者问题
我们思考一个问题
桌子上只有一个盘子,每次只可以向其中放入一个水果,爸爸专门向盘子中放入苹果,妈妈专门向盘子中放入橘子
儿子专门吃盘子中的橘子,女儿专门吃盘子中的苹果,只有盘子里边为空的时候,爸爸妈妈才能向其中放入水果
而且仅当盘子中有水果的时候 儿女才能拿走水果
然后我们先梳理关系
互斥关系
对盘子(缓冲区)的访问需要互斥进行
同步关系(一前一后)
爸爸在盘子里放入苹果 必须在女儿拿取苹果之前
妈妈在盘子里放入橘子 必须在儿子拿取橘子之前
只有盘子为空的时候 父母才可以放入水果
通过之前的学习 我们可以想到互斥:在临界区前后分别PV 同步 前V后P
semaphore mutex=1;//实现互斥访问盘子(缓冲区)
semaphore apple=0;//盘子中有几个苹果
semaphore orange=0;//盘子中有几个橘子
semaphore plate=1;//盘子中还可以放几个水果
dad(){
准备一个苹果
P(mutex);//实现互斥访问
P(plate);//能放入的水果数--
放入盘子一个苹果
V(apple);//放入一个苹果
V(mutex);
}
mom(){
准备一个橘子
P(mutex);
P(plate);
放入盘子一个橘子
V(orange);
V(mutex);
}
daughter(){
P(apple);//拿走苹果的前提是有苹果
P(mutex);
从盘子拿走一个苹果
V(plate);//能放入的水果数++
V(mutex);
吃苹果
}
son(){
P(orange);
P(mutex);
从盘子拿走一个橘子
V(plate);
V(mutex);
吃橘子
}
上述就是多生产者多消费者的问题的思路
所谓多不是生产者消费者个数多 是指生产者消费者种类多
如果我们仔细看代码并思考的话 我们可能发现如果没有实现互斥的变量mutex的话
程序是可以正常执行的
这是因为这个问题中的plate的初始值为1 如果初始值大于一
可能出现两个进程同时访问缓冲区的情况 导致写入的数据相互覆盖的情况
所以 如果缓冲区大小大于1 就必须设置一个互斥信号量mutex来保证互斥访问缓冲区
还有一点细心的朋友们可能发现了在儿子和女儿的代码中 互斥P操作在同步P操作后 这是避免发生死锁
P(orange);
P(mutex);
这个还是挺容易理解的吧 就是父母放水果和儿女拿水果不矛盾
这类问题我们要从事件角度考虑
盘子变空事件 到 放入水果事件
盘子变空事件可以由儿子引发也可能是女儿引发
放入水果事件 可能是父亲引发 也可能是母亲引发
以上就是两类生产者消费者问题 希望对大家有所帮助