首页 > 代码库 > 生产者消费者模式(转)
生产者消费者模式(转)
1.PV操作
PV操作是由P操作原语和V操作原语组成,对信号量进行操作。
P(S):意为占用,将信号量的值减1,S=S-1,如果S>=0,则该进程继续执行,否则进入等待队列;
V(S):意为释放,将信号量的值加1,S=S+1,如果S>0,则该进程继续执行,否则释放队列中第一个等待信号量的进程。
为了更形象的理解PV操作,可以联想一下电话亭场景:
P:第一个人占用电话亭打电话,可用电话亭数-1,S=S-1,接下来的人先检测S-1,如果S>=0,说明当前使用者有电话亭可用,如果S<0,说明无电话亭可用,S=-i说明自己刚好是第i个排队的人。
V:使用完电话亭就推门走开,将S加1,如果S>=2,说明这个人刚刚打电话时电话亭空闲一个;如果S=1,说明这个人刚好腾出一个空;如果S<=0说明有人排队,按照排队次序依次填补打电话。
2.同步和互斥
同步是进程之间直接的制约关系,体现工作次序,这种制约源于进程之间的合作,生产者和消费者关系就是同步关系。
互斥是进程之间间接的制约关系,这种制约源于对临界资源的访问,线程之间共享内存需要用到互斥关系。
生产者和消费者问题既是同步也是互斥的关系,一方面,作为平等进程,对缓冲区的访问时竞争关系,即互斥;另一方面,作为生产者和消费者两个进程有先后次序,存在合作关系所以是同步的。
3.生产者、消费者、缓冲区问题
①一个生产者,一个消费者,一个公共缓冲区: 只需保证,生产者先生产,消费者后消费,两者互斥使用缓冲区即可。m=1,n=0
生产者
{
生产产品
P(m)//保证生产者无法再生产
产品送往buffer
V(n)//唤醒消费者
}
消费者
{
P(n)//保证消费者不能先于生产者
从buffer取走产品
V(m)//唤醒生产者继续生产
消费产品
}
②一个生产者,一个消费者,无数个公共缓冲区:
与①不同在于,生产者可以不断生产,消费者可以不断消费,只需保证消费者有产品可消费。m=1,n=0
生产者
{
生产产品
P(m)
产品送往buffer
V(m)//可继续生产
V(n)//唤醒消费者
}
消费者
{
P(n)//保证有产品可消费,避免死锁
P(m)//阻止生产者生产
从buffer取走产品
V(m)//唤醒生产者生产
消费产品
}
注意点:P操作像是一个标志,进入临界区之前需要将互斥进程进行P操作,以免抢占资源
③一个生产者,一个消费者,n个环形缓冲区
与②类似,但②无限缓冲区即总有空闲区域可以生产,该情况需要检查缓冲区是否有空闲区域供生产,m=1,n=0,count=SIZEOFBUF
生产者
{
生产产品
P(count)//保证有空闲区域供生产,否则阻塞
P(m)
放入buffer
V(m)
V(n)//唤醒消费者
}
消费者
{
P(n)
P(m)
从buffer取产品
V(m)//唤醒生产者
V(count)//多空闲一个区域供生产者生产
消费产品
}
④两个生产者,两个消费者,一个公共缓冲区
两个生产者、两个消费者四者之间互斥使用公共缓冲区。增加两个互斥值,m=1.n=0
生产者
{
生产产品
P(m)//确定是生产者
放入buffer
V(n)//唤醒消费者
}
消费者
{
P(n)//保证有产品可消费
从buffer取产品
V(m)//唤醒生产者
}
⑤两个生产者,两个消费者,n环形缓冲区,count=SIZEOFBUF ,n=0,m =1,
生产者
{
生产产品
P(count)//保证有空闲区域供生产,否则阻塞
P(m)
放入buffer
V(m)
V(n)//唤醒消费者
}
消费者
{
P(n)
P(m)
从buffer取产品
V(m)//唤醒生产者
V(count)//多空闲一个区域供生产者生产
消费产品
}
原博客地址:http://www.cnblogs.com/aiheyiwen/p/4925810.html
自己的一点理解:其实P,V操作简单的可以理解为:我用了,给你用。当出现多个生产者,多个消费者的时候只需要在临界资源上互斥访问即可。
生产者消费者模式(转)