Matar el subproceso que se ejecuta dentro de un hilo

Estoy usando python 3.5.3 con PyQT 5 y he escrito GUI con él. Esta GUI ejecuta el código python de python con subprocess.run.

Para dejar mi GUI activa y no congelada durante la operación de subproceso, estoy ejecutando el subproceso en un subproceso.

En la GUI tengo el botón de parada que si el usuario presionó, quiero terminar el subproceso.

No tengo ningún problema para matar el hilo usando el método de terminación del hilo. Pero eso no termina el subproceso.

He intentado usar Popen en lugar de ejecutar, pero no puedo hacerlo para que se ejecute como subprocess.run. Además, prefiero usar la forma recomendada por Python que también me da la opción check_error

Así es como uso el subproceso:

class c_run_test_thread(QtCore.QThread): def __init__(self,test_file,log_file): QtCore.QThread.__init__(self) self.test_file = test_file self.log_file = log_file def __del__(self): self.wait() def run(self): # Thread logic try: # Run the test with all prints and exceptions go to global log file self.test_sub_process = subprocess.run(["python", self.test_file],stdout = self.log_file, stderr = self.log_file,check = True) except subprocess.CalledProcessError as error: print("Error : {}".format(error)) # Flush memory to file self.log_file.flush( def stop(self): # Flush memory to file self.log_file.flush() 

Y termino el hilo por

 # Stop test thread self.thread_run_test.terminate() 

Para resumir, quiero matar el hilo al mismo tiempo que mato su subproceso.

Puede haber otras formas más simples de hacerlo, pero lo que hice fue

  1. Use subprocess.Popen para ejecutar un subproceso, en lugar de subprocess.run , ya que este último no volverá antes de que finalice el proceso
  2. Compruebe si el proceso se termina con Popen.poll
  3. Mata el proceso usando Popen.kill

Un código de ejemplo sería algo. como el siguiente

 self.test_sub_process = subprocess.Popen(["python", self.test_file], stdout=self.log_file, stderr=self.log_file) 

Espera la terminación:

 print("Return code: {}".format(self.test_sub_process.wait())) 

O si quieres hacer algo mientras esperas:

 while self.test_sub_process.poll() is None: doSomething() print("Return code: {}".format(self.test_sub_process.poll())) 

Luego, en thread_run_test.terminate() , puedes matar el proceso

 self.test_sub_process.kill() 

HTH.