Python – seltsames Verhalten bei Warteschlangen, Managern und MultiprocessingPython

Python-Programme
Anonymous
 Python – seltsames Verhalten bei Warteschlangen, Managern und Multiprocessing

Post by Anonymous »

Als ich an einem meiner Lieblingsprojekte arbeitete, bei dem es um gleichzeitige Downloads mit dem Multiprocessing-Modul ging, stieß ich auf ein merkwürdiges Verhalten bei Queue-Objekten, die von einem multiprocessing.Manager()-Objekt generiert wurden.
Abhängig davon, wie ich ein Queue-Objekt (generiert durch einen Manager) in ein anderes Queue-Objekt einfüge (auch durch einen Manager generiert) erhalte ich ein anderes Verhalten, wenn ich meines Wissens nach dasselbe tue.
Hier ist ein minimales Arbeitsbeispiel:

Code: Select all

import multiprocessing
import Queue

def work(inbound_queue, keep_going):
while keep_going.value == 1:
try:
outbound_queue = inbound_queue.get(False) # this fails in case 3
#do some work
outbound_queue.put("work done!")
except Queue.Empty:
pass #this is busy wait of course, it's just an example

class Weird:
def __init__(self):
self.manager = multiprocessing.Manager()
self.queue = self.manager.Queue()
self.keep_going = multiprocessing.Value("i", 1)
self.worker = multiprocessing.Process(target = work, args = (self.queue, self.keep_going))
self.worker.start()
def stop(self): #close and join the second process
self.keep_going.value = 0
self.worker.join()
def queueFromOutside(self, q):
self.queue.put(q)
return q
def queueFromNewManager(self):
q = multiprocessing.Manager().Queue()
self.queue.put(q)
return q
def queueFromOwnManager(self):
q = self.manager.Queue()
self.queue.put(q)
return q

if __name__ == '__main__':
instance = Weird()
# CASE 1
queue = multiprocessing.Manager().Queue()
q1 = instance.queueFromOutside(queue) # Works fine
print "1: ", q1.get()

# CASE 2
q2 = instance.queueFromNewManager()   # Works fine
print "2: ", q2.get()

# CASE 3
q3 = instance.queueFromOwnManager()   # Error
print "3: ", q3.get()

instance.stop() #sadly never called :(
und seine Ausgaben (Python 2.7.10 x86, Windows).
AUSGABE für main:

Code: Select all

1:  work done!
2:  work done!
3:
Dann stürzt der Arbeitsprozess ab und q3.get() bleibt hängen.
AUSGABE für Arbeitsprozess:

Code: Select all

Process Process-2:
Traceback (most recent call last):
File "C:\Python27\lib\multiprocessing\process.py", line 258, in _bootstrap
self.run()
File "C:\Python27\lib\multiprocessing\process.py", line 114, in run
self._target(*self._args, **self._kwargs)
File "J:\Dropbox\Python\queues2.py", line 7, in work
outbound_queue = inbound_queue.get(False) # this fails in case 3
File "", line 2, in get
File "C:\Python27\lib\multiprocessing\managers.py", line 774, in _callmethod
raise convert_to_error(kind, result)
RemoteError:
---------------------------------------------------------------------------
Unserializable message: ('#RETURN', )
---------------------------------------------------------------------------
Die Frage ist also: Warum verursacht der 3. Fall einen RemoteError?
Das bereitgestellte Beispiel ähnelt nicht der Struktur des Codes im tatsächlichen Projekt, aber ich sende Warteschlangen an laufende Prozesse, und es funktioniert gut, wenn ich es mit den Methoden Nr. 1 und Nr. 2 mache. Es wäre jedoch schön, Methode Nr. 3 zu verwenden, da es die Mühe erspart, jedes Mal einen Manager zu besorgen, was überraschend lange dauern kann (~ 100 ms auf dem Computer, von dem aus ich gerade arbeite).
Die Frage kommt aus Neugier, da ich immer noch etwas über all die coolen Dinge im Multiprocessing-Modul lerne.
UPDATE, ich versuche das zu klären Frage: im Fall 3 (

Code: Select all

queueFromOwnManager
) Warum erstellt self.manager.Queue() eine Warteschlange, die nach dem Einfügen in self.queue nicht mit self.queue.get() abgerufen werden kann, während eine mit multiprocessing.Manager().Queue() erstellte Warteschlange abgerufen werden kann? Die Reihenfolge der Ausführung der 3 Fälle spielt keine Rolle. Im Idealfall ist „instance.queue“ vor und nach jedem der drei Methodenaufrufe in den drei Beispielen leer.
UPDATE 2: hat das Beispiel ähnlicher zu dem gemacht, was ich tatsächlich im Code mache

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post