Wenn ich eine multiprocessing.Queue
oder eine multiprocessing.Manager
(oder eines der anderen Synchronisationsprimitiven) teilen muss, gibt es einen Unterschied, indem Sie sie auf der globalen (Modul) definieren Ebene, im Gegensatz zu ihnen als Argument für die Funktion in einem anderen Prozess ausgeführt werden?Gemeinsame Nutzung von Synchronisationsobjekten über globalen Namespace vs als Funktionsargument
Zum Beispiel sind hier drei Möglichkeiten, ich kann eine Warteschlange vorstellt geteilt werden könnte:
# works fine on both Windows and Linux
from multiprocessing import Process, Queue
def f(q):
q.put([42, None, 'hello'])
def main():
q = Queue()
p = Process(target=f, args=(q,))
p.start()
print(q.get()) # prints "[42, None, 'hello']"
p.join()
if __name__ == '__main__':
main()
gegen
# works fine on Linux, hangs on Windows
from multiprocessing import Process, Queue
q = Queue()
def f():
q.put([42, None, 'hello'])
def main():
p = Process(target=f)
p.start()
print(q.get()) # prints "[42, None, 'hello']"
p.join()
if __name__ == '__main__':
main()
gegen
# works fine on Linux, NameError on Windows
from multiprocessing import Process, Queue
def f():
q.put([42, None, 'hello'])
def main():
p = Process(target=f)
p.start()
print(q.get()) # prints "[42, None, 'hello']"
p.join()
if __name__ == '__main__':
q = Queue()
main()
Welche den richtigen Ansatz ? Ich schätze aus meinen Experimenten, dass es nur der erste ist, aber ich wollte bestätigen, dass es offiziell der Fall ist (und nicht nur für Queue
, sondern für Manager
und andere ähnliche Objekte).
Die zweite sollte globale q am Anfang von f() haben? Die erste ist meiner Meinung nach die beste, nur weil die Objekte den richtigen Umfang haben, aber es ist nur eine Frage des Stils * IF * sie sind wirklich Singletons, und niemand ändert jemals den Code. Ein weiterer Grund, sie als Argumente zu übergeben, ist der Nachweis, dass Sie sie haben, und daher die Funktion korrekt aufrufen, obwohl dies besser in C++ und anderen stark typisierten Sprachen funktioniert, in denen der Compiler Buchhaltungsfehler für Sie auffängt, wenn Sie guten Stil verwenden. –
"global q" ist nicht erforderlich, wenn Sie ein globales Objekt nur über einen Methodenaufruf ändern, anstatt die Variable neu zuzuordnen, um auf ein neues Objekt zu verweisen. Wie gesagt, es scheint, dass 2 von 3 auf Windows nicht funktionieren, also denke ich, dass es keine Frage des Stils ist. Ich konnte einfach keine klare Erklärung in den Dokumenten finden, aber es scheint, dass das Überschreiten eines Parameters die einzige zuverlässige Technik ist. – max
Dies kann helfen: http://StackOverflow.com/Questions/37244168/Multiprocessing-Queue-Get-Hangs –