生产者指的是生产数据的任务,消费者指的是处理数据的任务。
在并发编程中,如果生产者比消费者速度快,那生产者需要等消费者处理完才能生产,反之,消费者需等生产者生产数据之后才能处理。
生产者消费者模型指的是生产者和消费者不直接通讯,通过一个容器(队列)来通讯,生产者生产得数据放进容器,消费者处理数据直接从容易里取,解决生产者和消费之间的强耦合问题(耦合关系是指某两个事物之间如果存在一种相互作用、相互影响的关系)。
from multiprocessing import Process,
import time,os
def producer(q):
for i in range(5):
time.sleep(0.1)
print('生产了一个包子%s' % i)
q.put(i)
def consumer(q):
while True:
q.get()
time.sleep(1)
print('吃了一个包子')
if __name__ == '__main__':
q = Queue() # 引入一个容器,队列
p = Process(target=producer, args=(q,))
c = Process(target=consumer, args=(q,))
p.start()
c.start()
print('主进程')
这时候会产生一个问题,消费者永远处于运行状态。其实,生产者生产完数据之后可以发送信号告诉消费者数据生产完毕,消费者接到信号之后,终止循环。
注意必须当所有的生产者都处理完毕后才能向队列中发送信号,而且有几个消费者要往队列里连续发几个信号,比较麻烦。
其实如果队列中的数据处理完,消费者没有存在的必要,可以将消费者设置为守护进程,随主进程的结束一块结束,那主进程应该在队列数据处理完才能结束,需要用到JoinableQueue,JoinableQueue是一个Queue对象,目的是让消费者取走的数据处理完毕后发送一个信号,告诉队列数据已处理。
from multiprocessing import Process,JoinableQueue
import time
def producer(q):
for i in range(5):
time.sleep(0.1)
print('生产了一个包子%s' % i)
q.put(i)
def consumer(q):
while True:
i = q.get()
time.sleep(1)
print('吃了一个包子%s' % i)
q.task_done() # 给生产者发信号,告诉从队列中取走的一个数据处理完
if __name__ == '__main__':
q = JoinableQueue() # 引入一个容器,队列
p = Process(target=producer, args=(q,))
c = Process(target=consumer, args=(q,))
c.daemon = True # 设置为守护进程
p.start()
c.start()
p.join() # 生产者生产完毕
q.join() # 队列数据已经处理完毕,主进程这时才可以结束,此时因数据处理完毕,消费者也没有存在的必要,随主进程一块结束,将消费者设置为守护进程
print('主进程')