Objet de connexion d'envoi Python 2.6 via Queue / Pipe / etc
-
22-07-2019 - |
Question
Donné ce bogue (numéro Python n ° 4892) qui provoque l'erreur suivante:
>>> 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
Quelqu'un connaît-il une solution de contournement pour passer un objet Connection dans une file d'attente?
Merci.
La solution
(Ce que je crois est) Une meilleure méthode, après avoir joué (je rencontrais le même problème. Voulais faire passer un tuyau à travers un tuyau.) avant de découvrir ce 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'
Je ne suis pas tout à fait sûr de savoir pourquoi cela est construit de cette manière (quelqu'un aurait besoin de mieux comprendre en quoi consiste la réduction du multitraitement dans ce domaine), mais cela fonctionne sans aucun doute et ne nécessite aucune importation de cornichons. Autre que cela, c'est assez proche de ce qui précède dans ce qu'il fait, mais plus simple. J'ai également ajouté cela au rapport de bogue python afin que d'autres personnes soient au courant de cette solution.
Autres conseils
Voici à peu près ce que j'ai fait:
# 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)
et
# 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 dernière ligne est cryptique et provient du texte suivant:
>>> upw
(<function rebuild_connection at 0x1005df140>,
(('/var/folders/.../pymp-VhT3wX/listener-FKMB0W',
17, False), True, True))
J'espère que cela aide quelqu'un d'autre. Cela fonctionne bien pour moi.