Comment arrêter immédiatement un sous-processus Python qui exécute des tests unitaires ?Terminer et tuer ne fonctionne pas

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

Question

J'ai une interface graphique Tkinter exécutant deux threads, la bande de roulement principale de l'interface graphique et un thread de travail.Le thread de travail crée un sous-processus à l'aide du code suivant :

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

Le fichier runTests.py effectue une configuration, puis exécute un fichier de test unitaire à l'aide de la commande suivante :

execfile('myUnitTests.py')

Le fichier myUnitTests.py contient plusieurs tests unitaires, dont certains prennent plus de cinq minutes à s'exécuter.Depuis l'interface graphique, je clique sur un bouton pour arrêter l'exécution des tests.Cela amène à son tour le thread de travail à envoyer un signal pour arrêter le sous-processus :

myProcess.terminate()

La commande terminate n'arrête pas le processus immédiatement, elle attend la fin de l'exécution du test unitaire en cours, puis elle termine le processus ?J'ai essayé d'utiliser os.kill mais j'obtiens les mêmes résultats qu'avec terminate().

Avez-vous une idée de la façon dont je peux rendre mon programme plus réactif afin qu'il tue immédiatement le sous-processus ?

Était-ce utile?

La solution

La documentation Python [ http://docs.python.org/library/signal.html ] dit:

  • Bien que les gestionnaires de signaux Python soient appelés de manière asynchrone en ce qui concerne l'utilisateur Python, ils ne peuvent apparaître qu'entre les instructions « atomiques » de l'interpréteur Python.Cela signifie que les signaux arrivant lors de longs calculs implémentés uniquement en C (comme les correspondances d'expressions régulières sur de grands corps de texte) peuvent être retardés pendant une durée arbitraire.

Donc, si votre test unitaire de cinq minutes effectue "un long calcul implémenté uniquement en C", et votre harnais de test unitaire installe un gestionnaire pour SIGTERM, c'est ton problème.Si c'est le cas, essayez myProcess.kill au lieu de myProcess.terminate (ou, si vous n'avez pas 2.6, myProcess.send_signal(9)). SIGKILL est inaccessible depuis l’espace utilisateur et devrait avoir un effet immédiat.

Avertissement:toutes les actions de nettoyage censées s'exécuter à la sortie de votre cadre de tests unitaires ne seront pas exécutées.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top