GNU/Linux >> Tutoriales Linux >  >> Linux

No se puede matar el script de Python con Ctrl-C

Creo que es mejor llamar a join() en tus hilos cuando esperas que mueran. Me he tomado la libertad de hacer que el cambio de sus bucles finalice (también puede agregar cualquier necesidad de limpieza que se requiera allí). La variable die se comprueba en cada pasada y cuando es True , el programa sale.

import threading
import time

class MyThread (threading.Thread):
    die = False
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name

    def run (self):
        while not self.die:
            time.sleep(1)
            print (self.name)

    def join(self):
        self.die = True
        super().join()

if __name__ == '__main__':
    f = MyThread('first')
    f.start()
    s = MyThread('second')
    s.start()
    try:
        while True:
            time.sleep(2)
    except KeyboardInterrupt:
        f.join()
        s.join()

KeyboardInterrupt y las señales solo son vistas por el proceso (es decir, el hilo principal) ... Eche un vistazo a Ctrl-c, es decir, KeyboardInterrupt para matar hilos en python


Ctrl +C finaliza el subproceso principal, pero debido a que sus subprocesos no están en modo daemon, siguen ejecutándose y eso mantiene vivo el proceso. Podemos convertirlos en demonios:

f = FirstThread()
f.daemon = True
f.start()
s = SecondThread()
s.daemon = True
s.start()

Pero luego hay otro problema:una vez que el hilo principal ha iniciado sus hilos, no hay nada más que hacer. Entonces sale, y los hilos se destruyen instantáneamente. Así que mantengamos vivo el hilo principal:

import time
while True:
    time.sleep(1)

Ahora mantendrá la impresión 'primero' y 'segundo' hasta que presione Ctrl +C .

Editar: como han señalado los comentaristas, es posible que los subprocesos del daemon no tengan la oportunidad de limpiar cosas como archivos temporales. Si lo necesita, tome el KeyboardInterrupt en el subproceso principal y hacer que coordine la limpieza y el apagado. Pero en muchos casos, dejar que los subprocesos de daemon mueran repentinamente probablemente sea lo suficientemente bueno.


Una versión mejorada de la respuesta de @Thomas K:

  • Definir una función de asistente is_any_thread_alive() de acuerdo con esta esencia, que puede terminar el main() automáticamente.

Códigos de ejemplo:

import threading

def job1():
    ...

def job2():
    ...

def is_any_thread_alive(threads):
    return True in [t.is_alive() for t in threads]

if __name__ == "__main__":
    ...
    t1 = threading.Thread(target=job1,daemon=True)
    t2 = threading.Thread(target=job2,daemon=True)
    t1.start()
    t2.start()

    while is_any_thread_alive([t1,t2]):
        time.sleep(0)

Linux
  1. Álgebra vectorial en Scientific Linux 7.1 con Python Script:Parte 1

  2. No se puede compilar Python.h – Error de instalación de Websockify

  3. ¿Ejecutar script con argumentos como usuario?

  4. El script Nohup para Python no funciona cuando se ejecuta en segundo plano con &

  5. Cómo detener manualmente un script de Python que se ejecuta continuamente en Linux

Cómo escribir un script Bash con ejemplos

Cómo ejecutar un comando de Shell con Python

Cómo ejecutar un script de Python en PHP

Cómo instalar Python 2.7 en CentOS 7.1 o 6.7 con Anaconda

¿Depuración en pyCharm con privilegios de sudo?

Haga que el script de Python combinado con paquetes de Linux sea fácil de instalar para el usuario final