Wie kann ich einen Python-Unterprozess, der Komponententests ausführt, sofort stoppen?Beenden und töten funktioniert nicht

StackOverflow https://stackoverflow.com/questions/3302910

Frage

Ich habe eine Tkinter-GUI, auf der zwei Threads laufen, der Haupt-Tread für die GUI und ein Worker-Thread.Der Arbeitsthread erstellt einen Unterprozess mit dem folgenden Code:

myProcess = subprocess.Popen(['python', '-u', 'runTests.py'],  
                         stdout=subprocess.PIPE, 
                         stderr=subprocess.STDOUT)

Die Datei runTests.py führt einige Setups durch und führt dann eine Unit-Test-Datei mit dem folgenden Befehl aus:

execfile('myUnitTests.py')

Die Datei myUnitTests.py enthält mehrere Komponententests, von denen einige mehr als fünf Minuten dauern.In der GUI klicke ich auf eine Schaltfläche, um die Ausführung der Tests zu stoppen.Dies wiederum veranlasst den Arbeitsthread, ein Signal zu senden, um den Unterprozess zu stoppen:

myProcess.terminate()

Der Terminate-Befehl stoppt den Prozess nicht sofort, sondern wartet, bis die Ausführung des aktuellen Komponententests abgeschlossen ist, und beendet dann den Prozess?Ich habe versucht, es zu verwenden os.kill aber ich bekomme die gleichen Ergebnisse wie mit terminate().

Irgendeine Idee, wie ich mein Programm reaktionsfähiger machen kann, sodass der Unterprozess sofort beendet wird?

War es hilfreich?

Lösung

Die Python-Dokumentation [ http://docs.python.org/library/signal.html ] sagt:

  • Obwohl Python-Signalhandler für den Python-Benutzer asynchron aufgerufen werden, können sie nur zwischen den „atomaren“ Anweisungen des Python-Interpreters auftreten.Dies bedeutet, dass Signale, die bei langen, rein in C implementierten Berechnungen eintreffen (z. B. Übereinstimmungen mit regulären Ausdrücken in großen Textkörpern), um eine beliebige Zeitspanne verzögert werden können.

Wenn Ihr fünfminütiger Unit-Test also „eine lange, rein in C implementierte Berechnung“ durchführt, Und Ihr Unit-Test-Kabelbaum installiert einen Handler für SIGTERM, das ist dein Problem.Wenn ja, versuchen Sie es myProcess.kill anstatt myProcess.terminate (oder, wenn Sie nicht 2,6 haben, myProcess.send_signal(9)). SIGKILL ist vom Benutzerbereich nicht abfangbar und sollte sofortige Wirkung haben.

Warnung:Alle Bereinigungsaktionen, die beim Verlassen Ihres Unit-Test-Frameworks ausgeführt werden sollen, werden nicht ausgeführt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top