2009-09-18 18 views
11

Dato this bug (Python Issue 4892) che dà luogo alla seguente errore:Python 2.6 send oggetto di connessione sopra coda/tubo/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 

Qualcuno sa di una soluzione per passare un oggetto Connection in una coda?

Grazie.

risposta

8

(quella che credo sia) Un metodo migliore, dopo un po 'suonare in giro (ho avuto lo stesso problema voleva passare un tubo attraverso un tubo..) Prima di scoprire questo 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' Non sono del tutto sicuro del motivo per cui è stato costruito in questo modo (qualcuno avrebbe bisogno di capire in che cosa consiste la parte di riduzione del multiprocessing per quello), ma sicuramente funziona e non richiede importazione di pickle. Oltre a questo, è abbastanza vicino a quanto sopra in quello che fa, ma più semplice. Ho anche gettato questo nel bug report di Python, così altri sanno della soluzione alternativa.

+0

Ottima risposta. Sicuramente sembra essere un'opzione migliore. –

+3

Questa è una buona risposta e funziona per me in 2.6. Tuttavia, in 2.7, quando viene chiamata la funzione 'reduction.rebuild_connection' AKA' reduced [0] ', il thread si blocca indefinitamente. –

+0

Ho lo stesso problema di @SamMagura. Qualcuno sa di una soluzione alternativa per Python 2.7? – redrah

7

Ecco più o meno quello che ho fatto:

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

e

# 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]) 

L'ultima riga è criptico, proveniente dalla seguente:

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

Speranza che aiuta a qualcun altro. Funziona bene per me.

+0

grazie, questa è una risposta molto utile, siamo rimasti davvero bloccati! – EdwardAndo

Problemi correlati