Kontextmanager und Pools für mehrere Prozesse
Angenommen, Sie verwenden einemultiprocessing.Pool
Objekt, und Sie verwenden dieinitializer
Einstellung des Konstruktors zur Übergabe einer Initialisierungsfunktion, die dann eine Ressource im globalen Namespace erstellt. Angenommen, die Ressource verfügt über einen Kontextmanager. Wie würden Sie mit dem Lebenszyklus der kontextverwalteten Ressource umgehen, vorausgesetzt, sie muss den gesamten Prozess überleben, aber am Ende ordnungsgemäß bereinigt werden?
Bisher habe ich etwas in der Art:
resource_cm = None
resource = None
def _worker_init(args):
global resource
resource_cm = open_resource(args)
resource = resource_cm.__enter__()
Ab hier können die Poolprozesse die Ressource nutzen. So weit, ist es gut. Aber das Aufräumen ist etwas kniffliger, da diemultiprocessing.Pool
Klasse bietet keinedestructor
oderdeinitializer
Streit.
Eine meiner Ideen ist die Verwendung desatexit
Modul, und registrieren Sie die Bereinigung im Initialisierer. Etwas wie das:
def _worker_init(args):
global resource
resource_cm = open_resource(args)
resource = resource_cm.__enter__()
def _clean_up():
resource_cm.__exit__()
import atexit
atexit.register(_clean_up)
Ist das ein guter Ansatz? Gibt es einen einfacheren Weg, dies zu tun?
BEARBEITEN:atexit
scheint nicht zu funktionieren. Zumindest nicht so, wie ich es oben benutze, daher habe ich derzeit noch keine Lösung für dieses Problem.