多方式实现生产者与消费者
生产者(producer)与消费者(consumer)
1.通过Queue队列实现
from multiprocessing import Queue
import time
import random
from multiprocessing import Process, Queue
def producer(q: Queue, name: str, food: str):
for i in range(1, 10 + 1):
time.sleep(random.uniform(0.1, 0.8))
print(f'{name}生产了{i}份{food}!')
q.put((i, food))
def consumer(q: Queue, name: str):
while True:
res = q.get()
if res is None:
break
time.sleep(random.uniform(0.1, 0.5))
print(f'{name}吃了{res[0]}份{res[1]}!')
if __name__ == '__main__':
q = Queue()
p1 = Process(target=producer, args=(q, '小日', '果冻'))
p1.start()
p2 = Process(target=producer, args=(q, '小月', '糖果'))
p2.start()
c = Process(target=consumer, args=(q, '小华'))
c.start()
p1.join()
p2.join()
q.put(None)
2.通过JoinableQueue实现
from multiprocessing import JoinableQueue
-
task_done()方法
比原先队列多了一个方法task_done(),当队列中的数据处理完会反馈给队列!
-
join()方法:
阻塞方法,当队列中的数据都task_done()完成后,join()就结束了,
这样可以让生产者与消费者更完美的处理完数据!
import time
import random
from multiprocessing import Process, JoinableQueue
def producer(q, name: str, food: str):
for i in range(1, 10 + 1):
time.sleep(random.uniform(0.1, 0.8))
print(f'{name}生产了{i}份{food}!')
q.put((i, food))
def consumer(q, name: str):
while True:
res = q.get()
time.sleep(random.uniform(0.1, 0.5))
print(f'{name}吃了{res[0]}份{res[1]}!')
q.task_done()
if __name__ == '__main__':
q = JoinableQueue()
p1 = Process(target=producer, args=(q, 'big', '果冻'))
p1.start()
p2 = Process(target=producer, args=(q, 'small', '棒冰'))
p2.start()
c = Process(target=consumer, args=(q, '小华'))
c.daemon = True
c.start()
p1.join() # p1和p2的阻塞是为了让数据都生产结束,这样队列才能反馈处理结果
p2.join()
q.join()# 当队列数据反馈都数据结束后,阻塞才会结束
3.通过管道Pipe实现
from multiprocessing import Pipe
在管道中有2端,在例题中我们取left,right,管道在子进程中传递了进去后,不使用的端我们要关闭,比如left,而在主进程中我们不使用right端,所以在left端发送完信息后,也要关闭right端口。
当管道中就剩下一个端口的时候,如果数据取完在继续取数据,就会出现EOFError
我们通过对于异常的捕获,让消费者实现循环的关闭,从而实现管道之间的数据生产和消费。注:管道是基于socket实现的所以收的时候会处于阻塞状态
from multiprocessing import Pipe, Process
import time
import random
def producer(left, right, name, food):
right.close()
for i in range(20):
time.sleep(random.uniform(0.1, 0.5))
print(f'{name}生产了{i}份{food}')
left.send((i, food))
left.close()
def consumer(left, right, name):
left.close()
while True:
try:
res = right.recv()
time.sleep(random.uniform(0.1, 0.5))
print(f'{name}吃了{res[0]}份{res[1]}')
except EOFError:
break
if __name__ == '__main__':
left, right = Pipe()
p1 = Process(target=producer, args=(left, right, 'Tom', '水果'))
p1.start()
c1 = Process(target=consumer, args=(left, right, '小明'))
c1.start()
p1.join()
left.close()
right.close()
c1.join()
print('主进程结束')

浙公网安备 33010602011771号