2011-12-21 6 views
5

Nauczyłem się ostatnio używać modułu wieloprocesorowego Python i czytania oficjalnego dokumentu. W dokumencie 16.6.1.2. Exchanging objects between processes znajduje się prosty przykład użycia potoku do wymiany danych.Python multiplerocessing pipe recv() doc niejasne czy czy brakowało mi czegoś?

A w 16.6.2.4. Connection Objects, jest to stwierdzenie, cytowany „Podnosi EOFError jeśli nie ma nic do otrzymania, a drugi koniec był zamknięty.”

Tak więc poprawiłem przykład pokazany poniżej. IMHO powinno to wywołać wyjątek: EOFError: nic nie zostało wysłane, a koniec wysyłający jest zamknięty.

Zmieniony kod:

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() 

Ale kiedy próbowałem zmieniony przykład na moim Ubuntu 11.04 maszynie, Python 2.7.2, skrypt powiesić.

Jeśli ktoś może wskazać mi, co przegapiłem, byłbym bardzo wdzięczny.

+0

proszę usunąć „lub ma błąd”. Prawdopodobieństwo błędu wynosi prawie zero. Skoncentruj się na prawdopodobnym wytłumaczeniu - źle odczytanej lub niejasnej dokumentacji. –

+0

@ S.Lott, miałeś rację. To moje przeoczenie - wcale nie błąd. Zapomniałem o liczeniu referencji Pythona i najlepszej praktyce korzystania z rur dupleksowych. – user183394

Odpowiedz

8

Po uruchomieniu nowego procesu z mp.Process proces potomny dziedziczy potoki rodzica. Gdy dziecko zamyka się conn, proces nadrzędny nadal ma otwartą child_conn, więc liczba referencyjna dla deskryptora pliku potoku jest nadal większa niż 0, a zatem EOFError nie jest wywoływany.

Aby uzyskać EOFError zamknąć końcówkę rury w obu procesach dominujących i podrzędnych:

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() 
Powiązane problemy