5

Mi while loop no sale cuando se presiona Ctrl + C. Parece que ignora mi excepción KeyboardInterrupt. La porción de bucle se ve así:pitón exit infinite while loop with KeyboardInterrupt excepción

while True: 
    try: 
    if subprocess_cnt <= max_subprocess: 
     try: 
     notifier.process_events() 
     if notifier.check_events(): 
      notifier.read_events() 
     except KeyboardInterrupt: 
     notifier.stop() 
     break 
    else: 
     pass 
    except (KeyboardInterrupt, SystemExit): 
    print '\nkeyboardinterrupt found!' 
    print '\n...Program Stopped Manually!' 
    raise 

Una vez más, no estoy seguro de cuál es el problema, pero mi terminal ni siquiera se imprime las dos alertas de impresión que tengo en mi excepción. ¿Alguien puede ayudarme a resolver este problema?

+2

Su primer 'excepto KeyboardInterrupt' atrapa la excepción. No será visible para el segundo 'excepto (KeyboardInterrupt, SystemExit)' si no lo vuelve a subir. – eumiro

+0

@eumiro - Comenté el primer KeyboardInterrupt y reemplacé el contenido de la excepción con 'pass', pero sigo teniendo el mismo problema. Ctrl + C está siendo ignorado (ps aux muestra que el proceso todavía se está ejecutando) – sadmicrowave

+0

@eumiro También intenté volver a subir la excepción KeyboardInterrupt agregando 'raise KeyboardInterrupt()' dentro del primer 'excepto KeyboardInterrupt:' sin embargo Todavía estoy experimentando el mismo problema. – sadmicrowave

Respuesta

11

reemplazar su declaración break con una declaración raise, como a continuación:

while True: 
    try: 
    if subprocess_cnt <= max_subprocess: 
     try: 
     notifier.process_events() 
     if notifier.check_events(): 
      notifier.read_events() 
     except KeyboardInterrupt: 
     notifier.stop() 
     print 'KeyboardInterrupt caught' 
     raise # the exception is re-raised to be caught by the outer try block 
    else: 
     pass 
    except (KeyboardInterrupt, SystemExit): 
    print '\nkeyboardinterrupt caught (again)' 
    print '\n...Program Stopped Manually!' 
    raise 

Las dos sentencias de impresión en los except bloques deben ejecutar con '(de nuevo)' que aparece en segundo lugar.

+0

Si bien no preguntó acerca de esto, la instrucción 'pass' en su código crea lo que se denomina spin-lock. Spin-locks consume CPU innecesariamente y puede afectar el rendimiento del sistema en general. Hay formas de evitarlos. Investigue utilizando objetos 'Queue.Queue' para comunicarse entre hilos, y' select.select' o el módulo 'multiprocesamiento' para comunicarse entre procesos. – wberry

+0

Por lo tanto, se me ocurre que mi principal problema (no creo que esté relacionado) es que he bifurcado mi script dos veces para 'demonizarlo'. Siendo ese el caso, KeyboardInterrupt ya no está conectado a la misma terminal (sin embargo, mi script todavía imprimirá salidas en la terminal activa). ¿Hay alguna manera de utilizar todavía KeyboardInterrupt (u otra forma de finalizar mi script manualmente) dentro de un programa daemonizado? – sadmicrowave

+0

actualmente he estado buscando el processid dentro de la salida 'ps aux' y ejecutando un' sudo kill [pid] '; sin embargo, esto no limpia elegantemente mi código antes de matarlo. Necesito cerrar las conexiones a la base de datos y eliminar los relojes inotify antes de matar el programa. – sadmicrowave