Come fermare una sottoprocessa Python che esegue i test dell'unità in esecuzione subito?Terminare e uccidere non funziona

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

Domanda

Ho una GUI Tkinter che esegue due fili, il battistrada principale per la GUI e un filo del lavoratore.Il filo del lavoratore crea una sottoprocesso utilizzando il seguente codice:

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

Il file runtests.py fa alcuni configurazione e quindi esegue un file di test dell'unità utilizzando il seguente comando:

execfile('myUnitTests.py')
.

Il file myunittests.py ha diversi test unità alcuni che richiedono oltre cinque minuti per essere eseguito. Dalla GUI, faccio clic su un pulsante per interrompere l'esecuzione dei test.Questo a sua volta rende il filo del lavoratore inviare un segnale per fermare la sottoprocesso:

myProcess.terminate()
.

Il comando terminato non interrompe immediatamente il processo, attende che il test dell'unità corrente finisca in esecuzione e quindi termina il processo? Ho provato ad usare os.kill ma ottengo gli stessi risultati come con terminate().

Qualche idea di come posso rendere il mio programma più reattivo in modo che uccida subito la sottoprocesso?

È stato utile?

Soluzione

La documentazione Python [ http://docs.python.org/library/signal.html ] dice:

.
    .
  • Sebbene i gestori di segnale Python siano chiamati asincrono per quanto riguarda l'utente Python, possono verificarsi solo tra le istruzioni "atomiche" dell'interprete di Python. Ciò significa che i segnali che arrivano durante lunghi calcoli implementati puramente in C (come le partite di espressione regolare su grandi corpi di testo) possono essere ritardati per una quantità arbitraria di tempo.

Quindi se il tuo test di unità di cinque minuti sta facendo "un lungo calcolo implementato puramente in c", e il cablaggio del test dell'unità installa un gestore per SIGTERM, questo è il tuo problema. In tal caso, prova myProcess.kill anziché myProcess.terminate (o, se non hai 2.6, myProcess.send_signal(9)). SIGKILL non è natchable dallo spazio utente e dovrebbe avere effetto immediato.

Avvertenza: eventuali azioni di pulizia che dovrebbero eseguire sulla via d'uscita dal quadro di prova dell'unità non verranno eseguite.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top