生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题,主要解决的是两者速率不一致而产生的阻抗不匹配。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
1.一个生产者,一个消费者,一个缓冲区。
问题关键:只有生产了产品,消费者才能消费(同步)
所以要定义2个同步信号量: empty–表示缓冲区是否为空,初值为1.
full–表示缓冲区中是否为满,初值为0
生产者进程
while(true){ produce(); P(empty); toBuffer(); V(full); }
消费者进程
while(true){ P(full); getBuffer(); V(empty); consume(); }
2.一个生产者,一个消费者,N个环形缓冲区
定义2个同步信号量:
empty–表示缓冲区是否为空,初值为n
full–表示缓冲区是否为满,初值为0
设缓冲区的编号为1~n-1,定义2个指针in和out,分别是生产者进程和消费者进程使用的指针,指向下一个可用的缓冲区。
生产者进程
while(true){ produce(); P(empty); toBuffer(in); in = (in + 1) mod n; V(full); }
消费者进程
while(true){ P(full); getBuffer(out); out=(out+1) mode n; V(empty); consume(); }
3.一组生产者,一组消费者,N个环形缓冲区
问题关键:生产者生产了产品,消费者才能消费;生产者之间不能往同一个缓冲区写数据;消费者也不能从同一个缓冲区读数据;
同步关系
互斥关系:
所以定义4个信号量:(几种关系,几个信号量)
该缓冲区的编号为1~n-1,定义两个指针in和out,分别是生产者进程和消费者进程使用的指针
生产者进程
while(true){ produce(); P(empty); P(mutex1); tobuffer(in); in = (in + 1) mod n; V(mutex1); V(full); }
消费者进程
while(true){ P(full); P(mutex2); getBuffer(out); out = (out + 1) mod n; V(mutex2); V(empty); }
实际上互斥还是同步,虽然有以上2种方式实现,但其根本还是原语的原子性。