python-multiprocessing-pool beenden
Arbeite ich auf einer renderfarm, und ich brauche meine Kunden, um in der Lage zu starten mehrerer Instanzen eines Renderers, ohne zu blockieren, so kann der Kunde erhalten neue Befehle. Ich habe, dass die Arbeit richtig, aber ich habe Probleme mit dem beenden der Prozesse erstellt.
Auf globaler Ebene definiere ich mein pool (so dass ich zugreifen kann, können Sie aus jeder Funktion):
p = Pool(2)
Ich dann meinen renderer mit apply_async:
for i in range(totalInstances):
p.apply_async(render, (allRenderArgs[i],args[2]), callback=renderFinished)
p.close()
Dass die Funktion abgeschlossen ist, startet die Prozesse im hintergrund, und wartet auf neue Befehle. Ich habe einen einfachen Befehl, töten den client und stoppen Sie die macht:
def close():
'close this client instance'
tn.write ("say "+USER+" is leaving the farm\r\n")
try:
p.terminate()
except Exception,e:
print str(e)
sys.exit()
sys.exit()
Scheint es nicht zu geben einen Fehler (es drucken würde, der den Fehler), die python beendet, aber der hintergrund-Prozesse ausgeführt werden. Kann jemand empfehlen, einen besseren Weg, die Kontrolle dieser Programme gestartet?
- Versuchen, aktivieren Sie die debug-Protokollierung mit
from multiprocessing import util; util.get_logger().setLevel(util.DEBUG)
und fügen Sie die Ausgabe. - Ich habe gesehen, Verhalten, wie dies vor, aber kann es nicht reproduzieren...jetzt Frage ich mich, wenn ein Aufruf von p.join() helfen würde, nach dem Aufruf von p.terminate()? Ich Frage mich auch, wenn Sie noch brauchen, um Anruf zu beenden und wenn Sie nur das tut, sys.exit() wird ordnungsgemäß Müll sammeln, den Pool und alle seine Prozesse.
- wenn ich versuche zum aktivieren der Protokollierung, ich bin immer dies in der Konsole:" Kein Handler gefunden werden konnte, der für den logger "multiprocessing". Leider, p.join() nach p.terminate() nicht einen Unterschied machen, und sys.exit() schließt die python lässt aber die Prozesse im hintergrund laufen.
- versuchen
multiprocessing.log_to_stderr().setLevel(logging.DEBUG)
. Tutrender()
starten weiterer Prozesse, z.B. mitsubprocess
Modul?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Fand ich die Lösung: stoppen Sie den pool in einem separaten thread, wie diesem:
Funktioniert gut, und immer habe ich getestet.
Wenn Sie das Problem weiterhin Auftritt, könntest du versuchen, die Simulation einer
Pool
mit dämonischen Prozesse (vorausgesetzt, Sie starten die pool - /Prozesse, die von einer nicht-dämonischen Prozess). Ich bezweifle, das ist die beste Lösung, da es scheint, wie IhrePool
Prozesse beenden, aber das alles konnte ich mit kommen. Ich weiß nicht, was Ihr Rückruf nicht, also bin ich nicht sicher, wo-in meinen Beispiel unten.Ich auch vorschlagen, versuchen, zu erstellen Ihre
Pool
im__main__
aufgrund meiner Erfahrung (und der Dokumentation) mit Verrücktheit, die Auftritt, wenn Prozesse, die erzeugt werden, weltweit. Dies gilt insbesondere, wenn Sie in Windows: http://docs.python.org/2/library/multiprocessing.html#windowsFand die Antwort auf meine eigene Frage. Das primäre problem war, dass ich den Aufruf einer Drittanbieter-Anwendung anstatt einer Funktion. Wenn ich den Aufruf des Unterprozess [entweder call() oder Popen()] erzeugt eine neue Instanz von python, deren einziger Zweck es ist, rufen Sie die neue Anwendung. Allerdings, wenn python verlässt, tötet diese neue Instanz von python und lassen Sie die Anwendung laufen.
Die Lösung ist, es zu tun die harte Weise, indem die pid des python-Prozess, der erstellt wird, bekommen die Kinder, die pid -, und tötet Sie. Dieser code ist spezifisch für osx; es ist einfacher code (das sich nicht auf grep) für linux verfügbar.