2011-12-21 19 views
5

He estado aprendiendo cómo usar el módulo de multiprocesamiento de Python recientemente, y leyendo el documento oficial. En 16.6.1.2. Exchanging objects between processes, hay un ejemplo simple sobre el uso de tuberías para intercambiar datos.Python multiprocessing pipe recv() doc confuso o ¿me perdí algo?

Y, en 16.6.2.4. Connection Objects, no es esta afirmación, citó "plantea EOFError si no hay nada izquierda para recibir y el otro extremo estaba cerrado."

Por lo tanto, revisé el ejemplo como se muestra a continuación. En mi humilde opinión, esto debería desencadenar una excepción EOFError: no se envió nada y se cierra el envío.

El código revisado:

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

Pero, cuando traté el ejemplo revisado en mi máquina de Ubuntu 11.04, Python 2.7.2, el guión colgar.

Si alguien me puede decir lo que me perdí, estaría muy agradecido.

+0

Por favor, retire la "o tiene error". La probabilidad de un error es casi cero. Enfóquese en la posible explicación: lectura incorrecta o documentación poco clara. –

+0

@ S.Lott, tenías razón. Es mi descuido, no es un error en absoluto. Olvidé el recuento de referencias de Python y la mejor práctica de usar tuberías dúplex. – user183394

Respuesta

8

Cuando se inicia un nuevo proceso con mp.Process, el proceso hijo hereda las canalizaciones del elemento primario. Cuando el hijo cierra conn, el proceso principal todavía tiene child_conn abierto, por lo que el recuento de referencia para el descriptor de archivo de tubería es aún mayor que 0, por lo que no se genera EOFError.

Para obtener el EOFError, cerrar el extremo de la tubería, tanto en los procesos padre e hijo:

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