2009-09-18 11 views
11

Compte tenu this bug (Python Issue 4892) qui donne lieu à l'erreur suivante:Python 2.6 envoi objet de connexion sur la file d'attente/tubes/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 

Est-ce que quelqu'un sait d'une solution de contournement pour passer un objet de connexion sur une file d'attente?

Merci.

Répondre

8

(Ce que je crois) Une meilleure méthode, après un certain jeu autour (je le même problème voulait passer un tuyau dans un tuyau..) Avant de découvrir ce poste:

>>> 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 Je ne suis pas tout à fait sûr pourquoi cela est construit de cette façon (quelqu'un aurait besoin d'un aperçu de ce que la réduction du multiprocessing est pour ça) mais cela fonctionne vraiment, et ne nécessite aucune importation de pickle. Autre que cela, c'est assez proche de ce qui précède dans ce qu'il fait, mais plus simple. J'ai également jeté cela dans le rapport de bug python afin que les autres connaissent la solution de contournement.

+0

Bonne réponse. Vraiment semble être une meilleure option. –

+3

Ceci est une bonne réponse, et travaille pour moi en 2.6. Cependant, dans 2.7, lorsque la fonction 'reduction.rebuild_connection' AKA' reduced [0] 'est appelée, le thread se bloque indéfiniment. –

+0

J'ai le même problème que @SamMagura. Est-ce que quelqu'un sait d'une solution de contournement pour Python 2.7? – redrah

7

est ici à peu près ce que je faisais:

# 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, venant de ce qui suit:

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

espoir qui aide quelqu'un d'autre. Ça fonctionne bien pour moi.

+0

merci, ceci est une réponse très utile, nous étions vraiment coincés! – EdwardAndo