1. 程式人生 > >python程序間通訊-Queue

python程序間通訊-Queue

在預設情況下,因為程序與程序之間是獨立的記憶體空間,無法進行資料的傳遞。如果我們需要程序間傳遞資料(即通訊)怎麼辦?
此時就可以使用Queue類來進行程序間的通訊。
在python中主要使用Queue、Pipe管道、強大的Manage支援管道通訊、套接字( socket )等等實現程序間通訊。我們主要介紹Queue如何使用來進行程序間的通訊。

一:程序(process)中的Queue

from multiprocessing import Queue,Process
import time

def write(q):
    for i in ["A","B","C","D","E"
]: print("向佇列中新增%s"%i) q.put(i) time.sleep(1) def read(q): while not q.empty(): print("從佇列中取出的值是%s"%q.get()) time.sleep(1) q = Queue() qw = Process(target=write,args=(q,)) qw.start() qw.join(0.1) qr = Process(target=read,args=(q,)) qr.start() qr.join() print("資料通訊完畢"
)

在上段程式碼中,我們應該知道:
(1) 在例項化Queue類,可以傳遞最大訊息數,如q = Queue(5),這段程式碼是指只允許訊息佇列中最大有5個訊息資料。如果不加最大訊息數或數量為負值,則表達不限制數量直到佔滿記憶體;
(2) Queue.qsize():返回當前佇列包含的訊息數量;
(3) Queue.empty():如果佇列為空,返回True,反之False ;
(4) Queue.full():如果佇列滿了,返回True,反之False;
(5) Queue.get([block[, timeout]]):獲取佇列中的一條訊息,然後將其從列隊中移除,block預設值為True;
1)如果block使用預設值,且沒有設定timeout(單位秒),訊息列隊如果為空,此時程式將被阻塞(停在讀取狀態),直到從訊息列隊讀到訊息為止,如果設定了timeout,則會等待timeout秒,若還沒讀取到任何訊息,則丟擲”Queue.Empty”異常;
2)如果block值為False,訊息列隊如果為空,則會立刻丟擲”Queue.Empty”異常;
(6) Queue.get_nowait():相當Queue.get(False);
(7) Queue.put(item,[block[, timeout]]):將item訊息寫入佇列,block預設值為True;
1)如果block使用預設值,且沒有設定timeout(單位秒),訊息列隊如果已經沒有空間可寫入,此時程式將被阻塞(停在寫入狀態),直到從訊息列隊騰出空間為止,如果設定了timeout,則會等待timeout秒,若還沒空間,則丟擲”Queue.Full”異常;
2)如果block值為False,訊息列隊如果沒有空間可寫入,則會立刻丟擲”Queue.Full”異常;
(8) Queue.put_nowait(item):相當Queue.put(item, False);

二:程序池(pool)中的Queue

如果要使用Pool建立程序,就需要使用multiprocessing.Manager()中的Queue(),而不是multiprocessing.Queue(),否則會得到一條如下的錯誤資訊:
RuntimeError: Queue objects should only be shared between processes through inheritance.

from multiprocessing import Manager,Pool
import time

def write(q):
    for i in ["A","B","C","D","E"]:
        print("向佇列中新增%s"%i)
        q.put(i)
        time.sleep(1)

def read(q):
    while not q.empty():
        print("從佇列中取出的值是%s"%q.get())
        time.sleep(1)


q = Manager().Queue()
pool = Pool()
pool.apply_async(write,args=(q,))
pool.apply_async(read,args=(q,))
# pool.apply(write,args=(q,))
# pool.apply(read,args=(q,))

pool.close()
pool.join()

print("資料通訊完畢")

程序和程序池Queue的區別在於:
1. 匯入的模組不一樣
2. 執行函式方式不一樣