什么是生产者消费者模式
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
例:
import time
from multiprocessing import Queue, Process
def producer(q):
for i in range(5):
res = '包子%s' % i
time.sleep(0.5)
print('生产者生产了%s' % res)
q.put(res)
def consumer(q):
while True:
res = q.get()
if res is None: break
time.sleep(1)
print('消费者吃了%s' % res)
if __name__ == '__main__':
# 容器
q = Queue()
# 生产者们
p1 = Process(target=producer, args=(q,))
p2 = Process(target=producer, args=(q,))
p3 = Process(target=producer, args=(q,))
# 消费者们
c1 = Process(target=consumer, args=(q,))
c2 = Process(target=consumer, args=(q,))
p1.start()
p2.start()
p3.start()
c1.start()
c2.start()
p1.join()
p2.join()
p3.join()
q.put(None) # 生产者给消费者发出信号,容器里没有包子了,有几个消费者就要发几次信号
q.put(None)
print('主')
结果:
生产者生产了包子0
生产者生产了包子0
生产者生产了包子0
生产者生产了包子1
生产者生产了包子1
生产者生产了包子1
生产者生产了包子2
消费者吃了包子0
生产者生产了包子2
消费者吃了包子0
生产者生产了包子2
生产者生产了包子3
生产者生产了包子3
生产者生产了包子3
生产者生产了包子4
消费者吃了包子0
生产者生产了包子4
消费者吃了包子1
生产者生产了包子4
主
消费者吃了包子1
消费者吃了包子1
消费者吃了包子2
消费者吃了包子2
消费者吃了包子2
消费者吃了包子3
消费者吃了包子3
消费者吃了包子3
消费者吃了包子4
消费者吃了包子4
消费者吃了包子4
当容器里没有包子的时候,需要生产者一一给消费者发出信号,如此显得比较low,JoinableQueue提供了一种解决此问题的方法。
import time
from multiprocessing import Process, JoinableQueue
def producer(q):
for i in range(5):
res = '包子%s' % i
time.sleep(0.5)
print('生产者生产了%s' % res)
q.put(res)
q.join() # 等消费者取没了再结束进程
def consumer(q):
while True:
res = q.get()
if res is None: break
time.sleep(1)
print('消费者吃了%s' % res)
q.task_done() # 消费者给生产者发信号
if __name__ == '__main__':
# 容器
q = JoinableQueue()
# 生产者们
p1 = Process(target=producer, args=(q,))
p2 = Process(target=producer, args=(q,))
p3 = Process(target=producer, args=(q,))
# 消费者们
c1 = Process(target=consumer, args=(q,))
c2 = Process(target=consumer, args=(q,))
c1.daemon = True
c2.daemon = True
p1.start()
p2.start()
p3.start()
c1.start()
c2.start()
p1.join()
p2.join()
p3.join() # 这一步执行完后,消费者已经将包子吃完了,所以应该设置消费者为守护进程
print('主')
结果:
生产者生产了包子0
生产者生产了包子0
生产者生产了包子0
生产者生产了包子1
生产者生产了包子1
生产者生产了包子1
生产者生产了包子2
消费者吃了包子0
生产者生产了包子2
消费者吃了包子0
生产者生产了包子2
生产者生产了包子3
生产者生产了包子3
生产者生产了包子3
生产者生产了包子4
消费者吃了包子0
生产者生产了包子4
消费者吃了包子1
生产者生产了包子4
消费者吃了包子1
消费者吃了包子1
消费者吃了包子2
消费者吃了包子2
消费者吃了包子2
消费者吃了包子3
消费者吃了包子3
消费者吃了包子3
消费者吃了包子4
消费者吃了包子4
消费者吃了包子4
主