假如創建了大量的進程,那進程間通信是必不可少的。python提供了多種進程間通信的方式,如:Queue和Pipe方法。他們兩者的區別在於Pipe常用來在兩個進程間通信,Queue用來在多個進程間實現通信;
Queue是多進程安全的隊列,可以使用queue實現多進程之間的數據傳遞。有兩個方法:Put 和 Get 可以進行 Queue 操作:
Put 方法用以插入數據到隊列中,他還有兩個可選參數:blocked 和 timeout。如果blocked 爲 True(默認值),並且timeout爲正值,該方法會阻塞timeout指定的時間,直到該隊列有剩餘的空間。如果超時,會拋出 Queue.Full異常。如果blocked爲False,但該Queue隊列已滿,會立即拋出Queue.Full異常。
Get 方法可以用隊列讀取並且刪除一個元素。同樣,Get方法有兩個可選參數:blocked和timeout。如果blocked爲True(默認值),並且timeout爲正值,那麼在等待時間內沒有取到任何元素,會拋出Queue.Empty異常。如果blocked爲False,分兩種情況:如果Queue有一個值可用,則立即放回該值;否則,如果隊列爲空,則立即拋出Queue.Empty異常。
示例:在父進程中創建三個子進程,兩個子進程往Queue中寫入數據,一個子進程從Queue中讀取數據。
# -*- coding: utf-8 -*-
# User: jier
# QQ: 2276845534
from multiprocessing import Process, Queue
import os, time, random
# 寫數據進程執行的代碼
def proce_write(q, urls):
print("Process (%s) is writing..." % os.getpid())
for url in urls:
q.put(url)
print("Put %s to queue..." % url)
time.sleep(random.random())
# 讀數據進程執行的代碼
def proc_read(q):
print('Process (%s) is writing...' %os.getpid())
while True:
url = q.get(True)
print('Get %s from queue.' % url)
if __name__ == "__main__":
# 父進程創建queue,並傳給各個子進程
q=Queue()
proc_writer1 = Process(target=proce_write, args=(q, ['url_1', 'url_2', 'url_3']))
proc_writer2 = Process(target=proce_write, args=(q, ['url_4', 'url_5', 'url_6']))
proc_reader = Process(target=proc_read, args=(q,))
# 啓動子進程 proc_write,寫入
proc_writer1.start()
proc_writer2.start()
# 啓動子進程proc_reader,讀取
proc_reader.start()
# 等待proc_writer結束
proc_writer1.join()
proc_writer2.join()
# proc_reader進程是死循環,無法等待其結束,只能強行終止,下面是強行終止的方法:
proc_reader.terminate()
輸出:
Process (12204) is writing...
Put url_1 to queue...
Process (12724) is writing...
Put url_4 to queue...
Process (5484) is writing...
Get url_1 from queue.
Get url_4 from queue.
Put url_2 to queue...
Get url_2 from queue.
Put url_3 to queue...
Get url_3 from queue.
Put url_5 to queue...
Get url_5 from queue.
Put url_6 to queue...
Get url_6 from queue.
Process finished with exit code 0