并发的程序常常会用到队列,用于进程/线程间的通讯。python
Python 中用于进程间通讯和线程间通讯的队列的接口是同样的,可是实现和效率倒是不一样的,一个最大的区别在于:进程间的队列在入队时会对数据进行序列化,而线程间的队列则不会序列化数据,这致使两者效率上会有明显的区别。这一点,文档上没有明确说明,可是能够本身经过实验来证明。并发
import queue from threading import Thread from multiprocessing import Queue, Process import time th_q = queue.Queue() proc_q = Queue() def th_worker(q): time.sleep(5) x = q.get() print('msg from thread queue: ' + str(x)) def proc_worker(q): time.sleep(5) x = q.get() print('msg from proc queue: ' + str(x)) th = Thread(target=th_worker, args=(th_q,)) th.start() p = Process(target=proc_worker, args=(proc_q,)) p.start() d = {'a':1, 'b':2} th_q.put(d) proc_q.put(d) time.sleep(1) d['a'] = 0 d['b'] = 5
运行上面的程序,结果是:线程
msg from thread queue: {'b': 5, 'a': 0}
msg from proc queue: {'b': 2, 'a': 1}
能够看出,线程间的队列上保存的是对象的引用,而非序列化的数据,而进程间的队列保存的是序列化的数据,因此不会随着原有对象的改变而改变。对象
注意d['a'] = 0 前一行的 time.sleep(1), 这一行对于验证两种队列的区别很是重要,若是没有这一行,结果就是这样的:blog
msg from thread queue: {'b': 5, 'a': 0}
msg from proc queue: {'b': 5, 'a': 0}
这是由于输入到队列的 item 的序列化动做是在一个队列内部的线程中进行的,不会占用使用队列的用户线程的计算时间。(这个队列内部的线程,multiprocess 模块的文档中略有说明:When a process first puts an item on the queue a feeder thread is started which transfers objects from a buffer into the pipe.)接口