队列:先进先出
堆栈:先进后出
利用队列实现进程通信
from multiprocessing import Queue q =Queue(5) #产生一个最多能够存放5个数据的队列 如果不写 默认就存放很多份 # q.put(1) #往队列中存放数据,如果存放的数据个数大于队列最大存储个数,程序会阻塞 # q.put(2) # q.put(3) # q.put(4) # print(q.full()) # False判断队列是否被存放满 # q.put(5) # print(q.full()) #True # q.put(6) # print(q.full()) # for i in range(1,6): q.put(i) #for循环往队列里面存放数据 # print(q.get()) #1 取数据,get一次就取一个 # print(q.get()) #2 # print(q.get()) #3 # print(q.empty()) #False # q.get_nowait() # 下面 4 就被这个获取了 不会显示 在队列有数据的情况下,跟get取值一样,当队列没有数据的情况下,取值直接报错 # print(q.get()) #4 # print(q.get()) #5 # print(q.empty()) #True 判断队列是否为空,需要注意的是,在并发的情况下,这个方法判断不准确 # print(q.get()) #如果队列为空,get会在原地等待队列中有数据过来 # print(q.get()) #如果队列为空,get会在原地等待队列中有数据过来 print(q.get()) #1 print(q.get()) #2 print(q.get()) #3 q.get_nowait() #4 不显示 print(q.empty()) #False 没有被取完 print(q.get()) #5 print(q.empty()) #True q.get_nowait() #没有值的话 会报错
基于队列实现进程与进程间通信
from multiprocessing import Queue,Process def producer(q): q.put('hello baby!') def consumer(q): print(q.get()) if __name__ == '__main__': q = Queue() #生成一个队列对象 p1 = Process(target=producer,args=(q,)) #子进程 p2 = Process(target=consumer,args=(q,)) #子进程 p1.start() p2.start() hello baby!
生产者消费者模型
生产者消费者模型:
生产者:做包子 生产数据的
消费者:买包子的 处理数据的
两者之间的通信介质:队列/管道
解决供需不平衡的问题
定义一个队列,用来存放固定数量的数据
解决一个生产者和消费者不需要直接打交道,两者都通过队列实现数据传输
Queue:管道+锁
from multiprocessing import Queue, Process # 队列 #创建进程 import time import random def producer(name, food, q): for i in range(1, 5): data = '%s生产的%s个%s' % (name, i, food) time.sleep(random.randint(1, 2)) print(data) q.put(data) # 将生产的数据放入队列中 def consumer(name, q): while True: data = q.get() #从队列里取数据 if data is None: break #队列里没有值的时候结束子进程 time.sleep(random.randint(1, 2)) print('%s吃了%s' % (name, data)) if __name__ == '__main__': q = Queue() # 生产一个队列对象 p1 = Process(target=producer, args=('大厨', '包子', q)) c1 = Process(target=consumer, args=('食客', q)) p1.start() c1.start() p1.join() #先让生产者结束后再执行下面的主进程的diamante print('主进程') # 主进程运行完后不会立刻结束 会等待子进程运行结束来回收子进程资源 #其中的一次结果: 大厨生产的1个包子 大厨生产的2个包子 食客吃了大厨生产的1个包子 食客吃了大厨生产的2个包子 大厨生产的3个包子 大厨生产的4个包子 主进程 食客吃了大厨生产的3个包子 食客吃了大厨生产的4个包子
from multiprocessing import Process, JoinableQueue #创建进程 等待队列结束 import time import random def producer(name,food,q): for i in range(1,5): data='%s:生产的第:%s个:%s'%(name,i,food) time.sleep(random.randint(1,2)) print(data) q.put(data) #将生产的数据放入队列中 def consumer(name,q): while True: data=q.get() if data is None:break time.sleep(random.randint(1,2)) print('%s吃了 %s'%(name,data)) q.task_done() #告诉你的队列,你已经将数据取出并且处理完毕 if __name__ == '__main__': q=JoinableQueue() #创建一个队列对象 p1=Process(target=producer,args=('厨子','蒸饺',q)) c1=Process(target=consumer,args=('吃货',q)) p1.start() c1.daemon=True #守护进程 主进程结束 立即让子进程结束 c1.start() p1.join() #等待生产者生产完所有的数据 #在生产者生产完数据之后,往队列里面放一个提示性的消息,告诉消费者已经没有了,你走吧。不要等了 # q.put(None) q.join() #等待队列中数据全部取出 print('主') """ 阻塞1:主进程等待生产者进程结束 生产者进程时间 消费者同时也在消费 阻塞2:队列数据必须取完才执行下面的主进程的下面代码 厨子:生产的第:1个:蒸饺 厨子:生产的第:2个:蒸饺 厨子:生产的第:3个:蒸饺 吃货吃了 厨子:生产的第:1个:蒸饺 厨子:生产的第:4个:蒸饺 吃货吃了 厨子:生产的第:2个:蒸饺 吃货吃了 厨子:生产的第:3个:蒸饺 吃货吃了 厨子:生产的第:4个:蒸饺 主 """