基于队列的进程通信
首先,进程之间的通信,对于数据来说都是隔离的,也就是说,进程之间本身是不能够通信的。
那么,想要实现进程之间的通信,就像老式的电话一样,需要一个“管道”,这里讲的就是队列Queue.
1.什么是队列?
队列的执行遵循的而原则是先进先出的原则,数据先进来的,理所应当先从队列中出去,就像排队打饭一样这个过程。
代码实现简单队列:
from multiprocessing import Queue # 创建一个队列,容纳8个元素 q = Queue(8) # 循环加值 for i in range(8): q.put(i) # 循环取值(取值正常,且程序正常, 前提是取得值小于等于加进去的值) for j in range(8): q.get(j) # 这种情况,就会阻塞,但不会报错,等待下次的取值 for j in range(9): q.get(j) q.empty() # 为了避免这种情况,我们这里告诉取完了,程序正常结束
2.实现基于队列的进程通信
之前所说的进程之间的数据是隔离的,数据是不可能相互得到的,下面利用队列能够实现简单的进程通信。
from multiprocessing import Process, Queue def task(q): q.put('hello wanglei') def task1(q): print(q.get()) if __name__ == '__main__': q = Queue() p1 = Process(target=task, args=(q,)) p2 = Process(target=task1, args=(q,)) p1.start() p2.start()
生产者消费者模型
为了基于形象的表达,这里举一个很简单的例子:
场景:想必大家都经历过卖包子的情况,一般做包子的人就是一个很简单的生产者的模型,他们负责生产包子给消费者吃,用户,也就是我们卖包子的人就是消费者。
生产者:做包子的 生产数据的
消费者:卖包子的 处理数据的
在这里面可定会出现下面两种情况:1.供不应求 2.供过于求
假设:如果有一个容器,做包子的师傅只要把做好的包子放在额定的盘子里,消费者负责从盘子里去包子。对于包子胜负来说,我只要盘子里包子少了,我就继续做,满足盘子是满的就行;对于卖包子的只要盘子里有我就可以买。这里盘子即使使用队列存放固定的数据。实现:
1 from multiprocessing import Process, JoinableQueue 2 import time, random 3 4 5 # 定义生产者 6 def producer(name, food, q): 7 for i in range(6): 8 data = '%s生产了%s食品' % (name, food) 9 print(data) 10 time.sleep(random.randint(1, 2)) 11 q.put(data) 12 13 14 # 定义消费者 15 def comsumer(name, q): 16 while True: 17 data = q.get() 18 if data is None: 19 break 20 time.sleep(random.randint(1, 2)) 21 res = '%s吃了%s食物*****' % (name, data) 22 print(res) 23 q.task_done() 24 25 26 if __name__ == '__main__': 27 # 定义一个队列,在数据取完是告诉生产者,数据没了 28 q = JoinableQueue() 29 p = Process(target=producer, args=('大厨王磊', '面包', q)) 30 p1 = Process(target=producer, args=('水果师傅王龙', '香蕉', q)) 31 c = Process(target=comsumer, args=('吃货周东', q)) 32 c1 = Process(target=comsumer, args=('dfsgsf', q)) 33 34 p.start() 35 p1.start() 36 # c.daemon = True 37 # c1.daemon = True 38 39 c.start() 40 c1.start()