¿Cómo detener un subproceso de Python que ejecuta pruebas unitarias de inmediato?Terminar y matar no funciona

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

Pregunta

Tengo una GUI de Tkinter ejecutando dos subprocesos, el hilo principal de la GUI y un subproceso de trabajo.El hilo de trabajo crea un subproceso usando el siguiente código:

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

El archivo runTests.py realiza algunas configuraciones y luego ejecuta un archivo de prueba unitaria usando el siguiente comando:

execfile('myUnitTests.py')

El archivo myUnitTests.py tiene varias pruebas unitarias, algunas de las cuales tardan más de cinco minutos en ejecutarse.Desde la GUI hago clic en un botón para detener la ejecución de las pruebas.Esto a su vez hace que el subproceso de trabajo envíe una señal para detener el subproceso:

myProcess.terminate()

¿El comando de terminación no detiene el proceso de inmediato, espera hasta que la prueba unitaria actual termine de ejecutarse y luego finaliza el proceso?He intentado usar os.kill pero obtengo los mismos resultados que con terminate().

¿Alguna idea de cómo puedo hacer que mi programa responda mejor para que finalice el subproceso de inmediato?

¿Fue útil?

Solución

La documentación de Python [ http://docs.python.org/library/signal.html ] dice:

  • Aunque los manejadores de señales de Python se llaman de forma asincrónica en lo que respecta al usuario de Python, solo pueden ocurrir entre las instrucciones "atómicas" del intérprete de Python.Esto significa que las señales que llegan durante cálculos largos implementados exclusivamente en C (como coincidencias de expresiones regulares en grandes cuerpos de texto) pueden retrasarse durante un período de tiempo arbitrario.

Entonces, si su prueba unitaria de cinco minutos realiza "un cálculo largo implementado exclusivamente en C", y El arnés de prueba de su unidad instala un controlador para SIGTERM, ese es tu problema.Si es así, intenta myProcess.kill en lugar de myProcess.terminate (o, si no tienes 2.6, myProcess.send_signal(9)). SIGKILL es imposible de capturar desde el espacio del usuario y debería tener efecto inmediato.

Advertencia:cualquier acción de limpieza que se supone que debe ejecutarse al salir de su marco de prueba unitaria no se ejecutará.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top