Pyhton中的隊列

併發的程序常常會用到隊列,用於進程/線程間的通訊。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.)接口

相關文章
相關標籤/搜索