Ich habe ein Python-Programm (genau genommen eine Django-Anwendung), das einen Subprozess mit % co_de startet % Aufgrund von Architektureinschränkungen meiner Anwendung kann ich subprocess.Popen
um den Subprozess zu beenden und Popen.terminate()
um zu überprüfen, wann der Prozess abgeschlossen ist beendet. Dies liegt daran, dass ich keinen Verweis auf den gestarteten Subprozess in einer Variablen halten kann.
Stattdessen muss ich die Prozess-ID Popen.poll()
in eine Datei pid
schreiben, wenn der Subprozess gestartet wird. Wenn ich den Subprozess stoppen möchte, öffne ich dieses pidfile
und verwende pidfile
um es zu stoppen.
Meine Frage ist: Wie kann ich herausfinden, wann der Subprozess wirklich beendet wurde? Unter Verwendung von os.kill(pid, signal.SIGTERM)
benötigt es ungefähr 1-2 Minuten, um nach dem Aufruf von signal.SIGTERM
endgültig zu enden. Zuerst dachte ich, dass os.kill()
das Richtige für diese Aufgabe wäre, aber wenn ich nenne es nach os.waitpid()
es gibt mir os.kill()
.
Übrigens starte und stoppe ich den Subprozess von einer HTML-Vorlage, die zwei Formulare verwendet, und die Programmlogik befindet sich in einer Django-Ansicht. Die Ausnahme wird in meinem Browser angezeigt, wenn sich meine Anwendung im Debug-Modus befindet. Es ist wahrscheinlich auch wichtig zu wissen, dass der Subprozess, den ich in meiner Sicht ( OSError: [Errno 10] No child processes
) aufruft, selbst einen anderen Subprozess aufruft, nämlich eine Instanz eines Scrapy Crawlers. Ich schreibe die python manage.py crawlwebpages
dieser Scrapy-Instanz in die pid
und das ist es, was ich beenden möchte.
Hier ist der relevante Code:
%Vor%Was kann ich tun? Vielen Dank!
BEARBEITEN:
Laut der großen Antwort von Jacek Konieczny , ich könnte mein Problem lösen, indem ich meinen Code in der Funktion pidfile
in folgendes ändere:
Der übliche Weg, um zu überprüfen, ob ein Prozess noch läuft, ist es, ihn mit dem Signal "0" zu töten (). Dies führt zu keinem laufenden Job und löst eine OSError
-Ausnahme mit errno=ESRCH
aus, wenn der Prozess nicht existiert.
Aber wann immer möglich, sollte der Aufrufer ein Elternteil des aufgerufenen Prozesses bleiben und die wait()
-Funktionsfamilie verwenden, um seine Beendigung zu behandeln. Das macht Popen
object.
Meine Lösung wäre, einen Zwischenprozess zu setzen, der die Unterverarbeitung steuert.
Ihre Web-Anfragen (die alle aufgrund von Parallelisierung in verschiedenen Prozessen vorkommen) teilen dem Kontrollprozess mit, ein bestimmtes Programm zu starten und es anzusehen; so schnell wie nötig fragen sie, was der Status ist.
Dieser Prozess wäre im einfachsten Fall ein Prozess, der einen UNIX-Domain-Socket öffnet (ein TCP / IP-Socket würde es auch tun) und ihn abhören. Der "Web-Prozess" stellt eine Verbindung her, sendet die Startanfrage und erhält eine eindeutige ID zurück. Anschließend kann er mit dieser ID weitere Fragen zum neuen Prozess stellen.
Alternativ gibt es die ID selbst (oder sie verwendet überhaupt keine ID, wenn es nur einen Prozess geben kann) und muss daher keine variable ID herumhalten.
Tags und Links python django subprocess