Wie Python threading-Code Multiprocessing-Code konvertieren?
-
28-09-2019 - |
Frage
Ich brauche eine threading
Anwendung auf eine multiprocessing
Anwendung aus mehreren Gründen (GIL, Speicherlecks) zu konvertieren. Zum Glück sind die Fäden ganz isoliert und kommunizieren nur über Queue.Queue
s. Diese primitive ist auch in multiprocessing
so alles sieht gut aus. Nun, bevor ich dieses Minenfeld betreten würde Ich mag einige Ratschläge über die bevorstehenden Probleme bekommen:
- Wie, um sicherzustellen, dass meine Objekte über den
Queue
übertragen werden können? Muss ich etwas__setstate__
bieten? - Kann ich vertrauen auf
put
sofort zurückkehrt (wie beithreading
Queue
s)? - Allgemeine Hinweise / Tipps?
- Alles, was sich lohnt zu lesen, abgesehen von der Python-Dokumentation ?
Lösung
Antwort auf Teil 1:
Alles, was durch ein multiprocessing.Queue
passieren muss (oder Pipe
oder was auch immer) muss sein, picklable . Dazu gehören grundlegende Typen wie tuple
s, list
s und dict
s. Auch Klassen unterstützt werden, wenn sie auf oberster Ebene und nicht zu kompliziert (überprüfen Sie die Details) sind. Der Versuch, lambda
s passieren um scheitern wird jedoch.
Antwort auf Teil 2:
A put
besteht aus zwei Teilen: Es dauert eine Semaphore, die Warteschlange zu ändern, und es beginnt ein optional feeder Gewinde. Also, wenn keine andere Process
versucht, die gleichen put
zugleich Queue
(zum Beispiel, weil es nur ein Process
schriftlich, es ist), sollte es schnell sein. Für mich stellte sich schnell genug für alle praktischen Zwecke erwiesen.
Teilantwort auf Teil 3:
- Die Ebene
multiprocessing.queue.Queue
fehlt einetask_done
Methode, so dass es nicht als Drop-in-Ersatz direkt verwendet werden kann. (Eine Unterklasse stellt das Verfahren). - Die alte
processing.queue.Queue
fehlt eineqsize
Methode und die neuere Versionmultiprocessing
ist ungenau (nur diese beachten). - Da filedescriptors normalerweise auf
fork
geerbt, Pflegebedarf zu schließen sie in den richtigen Prozesse genommen werden.