2011-12-21 10 views
5

私は最近、Pythonマルチプロセッシングモジュールの使い方を学び、公式の文書を読んでいます。 16.6.1.2. Exchanging objects between processesには、パイプを使ってデータを交換するという簡単な例があります。Pythonマルチプロセッシングパイプrecv()docが不明か何かが恋しくなったのですか?

16.6.2.4. Connection Objectsには、「受信メールが残っておらず、もう一方の端末が閉じていれば、EOFError」という引用文があります。

そこで、次のように例を修正しました。 IMHOこれは、EOFError例外を引き起こすはずです:何も送信されず、送信側が閉じられます。

改訂コード:

from multiprocessing import Process, Pipe 

def f(conn): 
    #conn.send([42, None, 'hello']) 
    conn.close() 

if __name__ == '__main__': 
    parent_conn, child_conn = Pipe() 
    p = Process(target=f, args=(child_conn,)) 
    p.start() 
    #print parent_conn.recv() # prints "[42, None, 'hello']" 
    try: 
     print parent_conn.recv() 
    except EOFError: 
     pass 
    p.join() 

しかし、私は私のUbuntu 11.04のマシンやPython 2.7.2で修正された例をしようとしたとき、スクリプトがハングアップします。

誰かが私が逃したものを指摘できれば、私は非常に感謝しています。

+0

「やバグがあり、」削除してください。バグの確率はほぼゼロです。可能性のある説明 - 誤った、または不明瞭な文書に焦点を当てる。 –

+0

@ S.Lott、あなたは正しいです。それは私の見落としです。バグではありません。 Pythonのリファレンスカウントとデュプレックスパイプを使うベストプラクティスを忘れてしまった。 – user183394

答えて

8

mp.Processで新しいプロセスを開始すると、子プロセスは親のパイプを継承します。子がconnを終了すると、親プロセスにはまだchild_connが開いているので、パイプファイル記述子の参照カウントはまだ0より大きく、EOFErrorは生成されません。 、例外EOFErrorを取得し、両方の親と子プロセスにパイプの端部を閉じるには

import multiprocessing as mp 

def foo_pipe(conn): 
    conn.close() 

def pipe(): 
    conn = mp.Pipe() 
    parent_conn, child_conn = conn 
    proc = mp.Process(target = foo_pipe, args = (child_conn,)) 
    proc.start() 
    child_conn.close() # <-- Close the child_conn end in the main process too. 
    try: 
     print(parent_conn.recv()) 
    except EOFError as err: 
     print('Got here') 
    proc.join() 

if __name__=='__main__': 
    pipe() 
関連する問題