#原创,转载请联系数据结构
咱们都知道,主进程和子进程之间不能共享全局变量。那么他们之间怎么实现通讯呢?函数
这就须要用到Queue(队列)了。spa
1.队列的简单介绍:线程
队列是常见的数据结构,采用先进先出的原则。从队列的尾部存数据,从队列的头部取数据。code
2.怎么建立一个队列:blog
q = multiprocessing.Queue()
括号里面能够传进去一个参数,表示队列的长度。队列
3.队列会出现的BUG?进程
import multiprocessing import time q = multiprocessing.Queue(3) q.put("1") q.put("2") q.put("3") print("队列是否为满?",q.full()) print("队列是否为空?",q.empty()) 输出: 队列是否为满? True 队列是否为空? True(False)
注意输出的地方。运行多几回,输出结果会不一样。有时候队列是否为空是True,有时候队列是否为False。出现True是什么缘由呢?ip
我已经把3个东西放进队列了啊,为何还会显示队伍为空是对的呢?缘由就是,put函数还没来的及把数据放进队列里,你就打印了出来了。get
而后你就会问,为何,还没把数据放进队列里,就会显示队伍是否为尽是对的呢?
缘由就是,这是Queue内部的一个机制。
内部的机制应该是这样子的,举个例子,有两个教室,两个教室都分别有一个指挥官。第一个教室的指挥官叫3个同窗去第二个教室,而后他就记在本子上了,有3个同窗已经去了第二个教室,对应的是,队列已经满了,打印输出,队列是否为尽是真的。
可是这3个学生还没走到第二个教室,第二个教室的指挥官就在本子上写,没有人来,对应的是,队列是空的,打印输出,队列是不是空的是真的。
可是学生若是走得快点,第二个教室的指挥官在本子上写,哎呀,有3个学生来了,对应的是,队列是满的,打印输出,队列是不是空的是假的。
4.队列的阻塞问题
若是一个队列最大的长度是3个,你put进去了4个。那么最后一个put的很理所固然的要等待。
可是,
最后一个等待的时候,会阻塞,使下面的代码不能运行。
import multiprocessing import time q = multiprocessing.Queue(3) q.put("1") q.put("2") q.put("3") q.put("4") print("队列是否为满?",q.full()) print("队列是否为空?",q.empty()) 输出: (输出为空,可是程序并无结束)
上述代码中,队列的最大长度是3,放进了3个后,正想放第4个,可是放不下了。那么第4个就只有在这里等待。可是他不只要等待,仍是阻塞状态。只有等他运行了,他下面的代码才能继续运行。
还有另外一种状况:
不单单是没地方放的时候会形成阻塞,若是队列为空,你要在里面拿东西,也会形成阻塞。
import multiprocessing q = multiprocessing.Queue(3) q.get() print("走开") print("我要吃汉堡包") 输出: (内容为空,且进程没有结束)
5.进程之间的通讯
说了这么多,该开始讲一下进程之间怎么实现通讯的了。
实现目标:咱们在主进程中建立两个子进程,一个用来把数据放在队列里,一个用来在队列里取数据,这样一来就实现了通讯的功能了吧。
import multiprocessing import time def put_data(queue): for i in "abcde": queue.put(i) time.sleep(0.5) print("把数据%s放在队列里:" % i) def get_data(queue): while not queue.empty(): time.sleep(0.5) data = queue.get() print("从队列拿到数据:%s" % data) if __name__ == '__main__': queue = multiprocessing.Queue(5) p1 = multiprocessing.Process(target=put_data,args=(queue,)) p1.start() p1.join() p2 = multiprocessing.Process(target=get_data, args=(queue,)) p2.start() p2.join() # 若是不加上p1.join和p2.join会发生很奇怪的BUG,get_data函数的里面的queue.empty会出现BUG,原理就是第3.所说的。
会致使p2线程误判为空,还没取完数据就结束任务了。
输出:
把数据a放在队列里:
把数据b放在队列里:
把数据c放在队列里:
把数据d放在队列里:
把数据e放在队列里:
从队列拿到数据:a
从队列拿到数据:b
从队列拿到数据:c
从队列拿到数据:d
从队列拿到数据:e
注意红色字的说明!去掉p1.join()和p2.join(),运行多几回,你会知道为何的。