簡體   English   中英

為什么Python多處理管道不安全?

[英]Why are Python multiprocessing Pipe unsafe?

我不明白為什么當有多個發送者和接收者時, Pipes被認為是不安全的。

如果是這種情況,如何使用Queues將以下代碼轉換為代碼? 關閉時Queues不會拋出EOFError ,因此我的進程無法停止。 我是否應該無休止地發送“Poison”消息告訴他們停止(這樣,我確定我的所有進程都至少收到一個毒葯)?

我想保持管道p1打開,直到我另有決定(這是我發送10條消息的時候)。


from multiprocessing import Pipe, Process
from random import randint, random
from time import sleep

def job(name, p_in, p_out):
    print(name + ' starting')
    nb_msg = 0
    try:
        while True:
            x = p_in.recv()
            print(name + ' receives ' + x)
            nb_msg = nb_msg + 1
            p_out.send(x)
            sleep(random())
    except EOFError:
        pass
    print(name + ' ending ... ' + str(nb_msg) + ' message(s)')

if __name__ == '__main__':
    p1_in, p1_out = Pipe()
    p2_in, p2_out = Pipe()

    proc = []

    for i in range(3):
        p = Process(target=job, args=(str(i), p1_out, p2_in))
        p.start()
        proc.append(p)

    for x in range(10):
        p1_in.send(chr(97+x))
    p1_in.close()
    for p in proc:
        p.join()
    p1_out.close()
    p2_in.close()

    try:
        while True:
            print(p2_out.recv())
    except EOFError:
        pass

    p2_out.close()

本質上,問題是Pipe是一個圍繞平台定義的管道對象的薄包裝器。 recv只是重復接收一個字節緩沖區,直到獲得完整的Python對象。 如果兩個線程或進程在同一個管道上使用recv ,則讀取可能會交錯,從而使每個進程都有半個pickle對象,從而破壞數據。 Queue在進程之間進行適當的同步,但代價是更復雜。

正如multiprocessing文檔所說:

請注意,如果兩個進程(或線程)同時嘗試讀取或寫入管道的同一端,則管道中的數據可能會損壞。 當然,同時使用管道的不同端的進程不存在損壞的風險。

你不必無休止地送毒葯; 每個工人一個就是你所需要的。 每個工人在退出之前都會拿出一個毒丸,所以工人不會錯過這個消息。

您還應該考慮使用multiprocessing.Pool而不是重新實現“工作進程”模型 - Pool有很多方法可以很容易地跨多個線程分配工作。

我不明白為什么當有多個發送者和接收者時,管道被認為是不安全的。

考慮您同時將水從源A和B放入管道中。 在管道的另一端,你不可能找出哪一部分水來自A或B,對嗎? :)

管道在字節級別上傳輸數據流。 如果沒有通信協議,它就不知道消息是什么,因此無法確保消息的完整性。 因此,使用具有多個發件人的管道不僅“不安全”。 這是一個重大的設計缺陷,很可能會導致溝通問題。

但是,隊列是在更高級別上實現的。 它們用於傳遞消息 (甚至是抽象對象)。 隊列用於保持消息/對象自包含。 多個源可以將對象放入隊列中,並且多個消費者可以拉動這些對象,同時100%確定作為一個單元進入隊列的任何內容也作為一個單元出現。

編輯了很長一段時間后:

我應該在字節流中添加,所有字節的檢索順序與發送(保證)相同。 多個發件人的問題是發送順序(輸入順序)可能已經不清楚或隨機,即多個流可能以不可預測的方式混合。

通用隊列實現可確保單個消息保持不變,即使有多個發件人也是如此。 消息也按發送的順序檢索。 但是,對於多個競爭發送器而沒有進一步的同步機制,再次無法保證輸入消息的順序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM