2009-09-18 18 views
11

Biorąc this bug (Python Issue 4892) który daje podstawę do następującego błędu:Python 2.6 wyślij obiekt połączenia na kolejkę/Rura/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 

Czy ktoś wie o obejście aby przekazać obiekt połączenia w kolejce?

Dziękuję.

Odpowiedz

8

(co moim zdaniem jest) lepsza metoda, po jakimś zabawy (ja miałem ten sam problem chcielibyście przekazać rury przez rurę..) Przed odkryciem tego posta:

>>> 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 nie jestem do końca pewien, dlaczego tak jest zbudowane (ktoś potrzebowałby wglądu w to, do czego służy ta redukcyjna część wieloprocesowości), ale z pewnością działa i nie wymaga importu pikli. Poza tym jest to dość zbliżone do powyższego w tym, co robi, ale prostsze. Wrzuciłem to również do raportu o błędach Pythona, aby inni wiedzieli o obejściu tego problemu.

+0

Świetna odpowiedź. Zdecydowanie wygląda na lepszą opcję. –

+3

To jest dobra odpowiedź i działa dla mnie w 2.6. Jednak w 2.7, gdy wywoływana jest funkcja 'reduction.rebuild_connection' AKA' zmniejszona [0] ', wątek blokuje się w nieskończoność. –

+0

Mam ten sam problem co @SamMagura. Czy ktoś wie o obejściu dla Pythona 2.7? – redrah

7

Oto z grubsza to, co zrobiłem:

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

i

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

Ostatni wiersz jest tajemnicze, pochodzących z następujących opcji:

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

nadzieję, że pomoże kogoś innego. Działa to dobrze dla mnie.

+0

dziękuję, to bardzo przydatna odpowiedź, naprawdę utknęliśmy! – EdwardAndo

Powiązane problemy