excepciones - keyboardinterrupt python 3
el subprocesamiento ignora la excepción KeyboardInterrupt (5)
Leve modificación de la solución de ubuntu.
Eliminando tread.daemon = True según lo sugerido por Eric y reemplazando el bucle de suspensión por signal.pause ():
import signal
try:
thread=reqthread()
thread.start()
signal.pause() # instead of: while True: time.sleep(100)
except (KeyboardInterrupt, SystemExit):
print ''/n! Received keyboard interrupt, quitting threads./n''
Estoy ejecutando este mi código simple:
import threading, time
class reqthread ( threading.Thread ):
def __init__ (self):
threading.Thread.__init__(self)
def run ( self ):
for i in range(0,10):
time.sleep(1)
print ''.''
try:
thread=reqthread()
thread.start()
except (KeyboardInterrupt, SystemExit):
print ''/n! Received keyboard interrupt, quitting threads./n''
Pero cuando lo ejecuto, imprime
$ python prova.py
`
.
.
^C.
.
.
.
.
.
.
.
Exception KeyboardInterrupt in <module ''threading'' from ''/usr/lib/python2.6/threading.pyc''> ignored
`
De hecho, el subproceso de Python ignora la interrupción de mi teclado Ctrl + C y no imprime la Received Keyboard Interrupt
. ¿Por qué? ¿Qué está mal con este código?
Mi (hacky) solución es para el parche de mono Thread.join()
esta manera:
def initThreadJoinHack():
import threading, thread
mainThread = threading.currentThread()
assert isinstance(mainThread, threading._MainThread)
mainThreadId = thread.get_ident()
join_orig = threading.Thread.join
def join_hacked(threadObj, timeout=None):
"""
:type threadObj: threading.Thread
:type timeout: float|None
"""
if timeout is None and thread.get_ident() == mainThreadId:
# This is a HACK for Thread.join() if we are in the main thread.
# In that case, a Thread.join(timeout=None) would hang and even not respond to signals
# because signals will get delivered to other threads and Python would forward
# them for delayed handling to the main thread which hangs.
# See CPython signalmodule.c.
# Currently the best solution I can think of:
while threadObj.isAlive():
join_orig(threadObj, timeout=0.1)
else:
# In all other cases, we can use the original.
join_orig(threadObj, timeout=timeout)
threading.Thread.join = join_hacked
Para resumir los cambios recomendados en the comments , lo siguiente me funciona bien:
try:
thread = reqthread()
thread.start()
while thread.isAlive():
thread.join(1) # not sure if there is an appreciable cost to this.
except (KeyboardInterrupt, SystemExit):
print ''/n! Received keyboard interrupt, quitting threads./n''
sys.exit()
Poner la try ... except
en cada hilo y también un signal.pause()
en true main()
funciona para mí.
Sin embargo, ten cuidado con el bloqueo de importación . Supongo que es por eso que Python no resuelve ctrl-C por defecto.
Tratar
try:
thread=reqthread()
thread.daemon=True
thread.start()
while True: time.sleep(100)
except (KeyboardInterrupt, SystemExit):
print ''/n! Received keyboard interrupt, quitting threads./n''
Sin la llamada al time.sleep
, el proceso principal está saltando del try...except
bloqueo demasiado temprano, por lo que el KeyboardInterrupt
no se detecta. Lo primero que pensé fue utilizar thread.join
, pero parece que bloquea el proceso principal (ignorando KeyboardInterrupt) hasta que finalice el thread
.
thread.daemon=True
hace que el hilo termine cuando finaliza el proceso principal.