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 :(
AUSGABE für main:
Code: Select all
1:  work done!
2:  work done!
3:
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', )
---------------------------------------------------------------------------
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
queueFromOwnManagerUPDATE 2: hat das Beispiel ähnlicher zu dem gemacht, was ich tatsächlich im Code mache
 Mobile version
 Mobile version