2009-09-18 3 views
11

Dada this bug (Python Issue 4892) que da lugar al error siguiente:Python 2.6 Objeto de envío conexión a través de la cola/Tubería/etc

>>> import multiprocessing 
>>> multiprocessing.allow_connection_pickling() 
>>> q = multiprocessing.Queue() 
>>> p = multiprocessing.Pipe() 
>>> q.put(p) 
>>> q.get() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File  "/.../python2.6/multiprocessing/queues.py", line 91, in get 
    res = self._recv() 
TypeError: Required argument 'handle' (pos 1) not found 

¿Alguien sabe de una solución alternativa para pasar un objeto de conexión en una cola?

Gracias.

Respuesta

8

(Lo que yo creo es) Un método mejor, después de algún jugando (que estaba teniendo el mismo problema que debemos pasar de una tubería a través de una tubería..) Antes de descubrir este post:

>>> from multiprocessing import Pipe, reduction 
>>> i, o = Pipe() 
>>> reduced = reduction.reduce_connection(i) 
>>> newi = reduced[0](*reduced[1]) 
>>> newi.send("hi") 
>>> o.recv() 
'hi' 

I' No estoy completamente seguro de por qué esto se construye de esta manera (alguien necesitaría una visión de qué diablos es la parte de reducción del multiprocesamiento para eso) pero definitivamente funciona, y no requiere importación de salmuera. Aparte de eso, es bastante similar a lo anterior en lo que hace, pero más simple. También lancé esto en el informe de errores de Python para que otros sepan de la solución.

+0

Gran respuesta. Definitivamente parece ser una mejor opción. –

+3

Esta es una buena respuesta, y funciona para mí en 2.6. Sin embargo, en 2.7, cuando se llama a la función 'reduction.rebuild_connection' AKA' reduced [0] ', el hilo se bloquea indefinidamente. –

+0

Tengo el mismo problema que @SamMagura. ¿Alguien sabe de una solución para Python 2.7? – redrah

7

Aquí es más o menos lo que hice:

# Producer 
from multiprocessing.reduction import reduce_connection 
from multiprocessing import Pipe 

    # Producer and Consumer share the Queue we call queue 
def handle(queue): 
    reader, writer = Pipe() 
    pickled_writer = pickle.dumps(reduce_connection(writer)) 
    queue.put(pickled_writer) 

y

# Consumer 
from multiprocessing.reduction import rebuild_connection 

def wait_for_request(): 
    pickled_write = queue.get(block=True) # block=True isn't necessary, of course 
    upw = pickle.loads(pickled_writer) # unpickled writer 
    writer = upw[0](upw[1][0],upw[1][1],upw[1][2]) 

La última línea es críptica, que viene de lo siguiente:

>>> upw 
(<function rebuild_connection at 0x1005df140>, 
(('/var/folders/.../pymp-VhT3wX/listener-FKMB0W', 
17, False), True, True)) 

la esperanza de que ayude a alguien más. Funciona bien para mí.

+0

gracias, esta es una respuesta muy útil, ¡estábamos realmente atascados! – EdwardAndo

Cuestiones relacionadas