Python 2.6 envía un objeto de conexión a través de Queue / Pipe / etc
-
22-07-2019 - |
Pregunta
Dado este error (Python Issue 4892) que da lugar al siguiente error:
>>> 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 Connection en una Cola?
Gracias.
Solución
(Lo que creo es) Un método mejor, después de jugar un poco (estaba teniendo el mismo problema. Quería pasar una tubería a través de una tubería) antes de descubrir esta publicación:
>>> from multiprocessing import Pipe, reduction
>>> i, o = Pipe()
>>> reduced = reduction.reduce_connection(i)
>>> newi = reduced[0](*reduced[1])
>>> newi.send("hi")
>>> o.recv()
'hi'
No estoy completamente seguro de por qué esto se construye de esta manera (alguien necesitaría una idea de qué diablos se trata la parte de reducción del multiprocesamiento), pero definitivamente funciona y no requiere importar encurtidos. Aparte de eso, es bastante similar a lo anterior en lo que hace, pero más simple. También incluí esto en el informe de errores de Python para que otros conozcan la solución.
Otros consejos
Esto 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 y proviene de lo siguiente:
>>> upw
(<function rebuild_connection at 0x1005df140>,
(('/var/folders/.../pymp-VhT3wX/listener-FKMB0W',
17, False), True, True))
Espero que ayude a alguien más. Funciona bien para mí.