python 多進程-進階-進程間通信之Queue

    假如創建了大量的進程,那進程間通信是必不可少的。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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章