5

Il mio ciclo while non esce quando viene premuto Ctrl + C. Apparentemente ignora la mia eccezione KeyboardInterrupt. La porzione di anello assomiglia a questo:python exit infinito while loop con KeyboardInterrupt exception

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 

Anche in questo caso, non sono sicuro di quale sia il problema, ma il mio terminale non stampa anche i due avvisi di stampa che ho nella mia eccezione. Qualcuno può aiutarmi a capire questo problema?

+2

Il tuo primo 'except KeyboardInterrupt' intercetta l'eccezione. Non sarà visibile al secondo 'except (KeyboardInterrupt, SystemExit)' se non lo si controrilancia. – eumiro

+0

@eumiro - Ho commentato il primo KeyboardInterrupt e ho sostituito il contenuto dell'eccezione con 'pass', ma sto ancora riscontrando lo stesso problema. Ctrl + C viene ignorato (ps aux mostra anche il processo ancora in esecuzione) – sadmicrowave

+0

@eumiro Ho anche provato a controrilanciare l'eccezione KeyboardInterrupt aggiungendo 'raise KeyboardInterrupt()' nel primo 'except KeyboardInterrupt:' tuttavia I sto ancora vivendo lo stesso problema. – sadmicrowave

risposta

11

Sostituire la sua dichiarazione break con una dichiarazione raise, come di seguito:

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 

Le due dichiarazioni di stampa nei except blocchi devono eseguire con '(di nuovo)' apparire secondo.

+0

Anche se non l'hai chiesto, l'istruzione 'pass' nel tuo codice crea quello che viene chiamato spin-lock. Gli spin-lock consumano CPU inutilmente e possono influire sulle prestazioni dell'intero sistema. Ci sono modi per evitarli. Indagare utilizzando gli oggetti 'Queue.Queue' per comunicare tra thread e' select.select' o il modulo 'multiprocessing' per comunicare tra processi. – wberry

+0

Quindi, mi viene in mente che il mio problema principale (pensavo di non essere correlato) è che ho biforcuto il mio script due volte per "demonizzarlo". Stando così le cose, KeyboardInterrupt non è più collegato allo stesso terminale (tuttavia, il mio script stamperà ancora le uscite sul terminale attivo). C'è un modo per utilizzare ancora KeyboardInterrupt (o un altro modo per terminare manualmente il mio script) all'interno di un programma demonizzato? – sadmicrowave

+0

attualmente sto cercando il processid all'interno dell'output di 'ps aux' ed eseguo un' sudo kill [pid] '; tuttavia, questo non pulisce il mio codice con grazia prima di ucciderlo. Ho bisogno di chiudere le connessioni del database e rimuovere gli orologi inotify prima di uccidere il programma. – sadmicrowave