2011-07-06 26 views
8

Teclado Interrumpe en inactividad el 90% de las veces, pero me preguntaba por qué no siempre funcionan. En espera, si hagoPython Inactivo y TecladoInterrupciones

import time 
time.sleep(10) 

y luego intentar una KeyboardInterrupt usando Ctrl + C, que no interrumpe el proceso hasta después de dormir durante 10 segundos.

El mismo código y un teclado Interrumpir a través de Ctrl + C funciona inmediatamente en el shell.

+0

¿Qué versión de Python? ¿Qué plataforma y sistema operativo? –

+0

Python 2.7 en Windows XP. Gracias. – cssndrx

+0

En mi sistema Linux, encontré que cuando CTRL + C no funciona, al ingresar el comando de terminal 'kill -2 'se detendrá Idle. – JB0x2D1

Respuesta

6

Un rápido vistazo a la fuente IDLE revela que KeyboardInterrupts tienen alguna manipulación caso especial: http://svn.python.org/view/python/tags/r267/Lib/idlelib/PyShell.py?annotate=88851

Además de eso, el código es realmente ejecutados en un proceso separado que el proceso principal IDLE GUI comunica con a través de RPC. Vas a obtener un comportamiento diferente bajo ese modelo - que es mejor para probar simplemente con el intérprete canónica (a través de línea de comandos, interactiva, etc.)

============

Profundizando ...

la toma en el servidor de RPC es administrado en un subproceso secundario que se supone para propagar una KeyboardInterrupt mediante una llamada a thread.interrupt_main() (http://svn.python.org/view/python/tags/r267/Lib/idlelib/run.py?annotate=88851). El comportamiento no es el esperado ... Esta publicación sugiere que, por alguna razón, interrupt_main no proporciona el nivel de granularidad esperado: http://bytes.com/topic/python/answers/38386-thread-interrupt_main-doesnt-seem-work

Las funciones de la API Async en cPython son un poco tontas (según mi experiencia) debido a cómo se maneja el lazo del intérprete, entonces no me sorprende. interrupt_main() llama a PyErr_SetInterrupt() para notificar asincrónicamente al intérprete para manejar un SIGINT en el hilo principal. De http://docs.python.org/c-api/exceptions.html#PyErr_SetInterrupt:

Esta función simula el efecto de una señal SIGINT llegar - los próximos PyErr_CheckSignals de tiempo() se llama, KeyboardInterrupt se elevará

que requeriría que el intérprete que ir aunque cualquier cantidad de instrucciones de bytecode antes de que se vuelva a llamar a PyErr_CheckSignals(), algo que probablemente no ocurra durante un time.sleep(). Me atrevería a decir que es una verruga de simular un SIGINT en lugar de señalar un SIGINT.

+0

+1 para "prueba con el intérprete canónico". Especialmente cuando se trata de Idle, que tiene una tendencia real a tener muchos comportamientos mágicos. Mi recomendación para cualquier persona es que si realmente quiere usar Idle todavía tiene una ventana de terminal/comando abierta para hacer las pruebas reales. –

1

ver este article:

cito:

Si intenta detener un programa CPython utilizando Control-C, el intérprete emite una excepción KeyboardInterrupt.

Tiene sentido, porque el hilo está dormido durante 10 segundos y, por lo tanto, no se pueden emitir excepciones hasta que pasen los 10 segundos. Sin embargo, ctrl + c siempre funciona en el shell porque está intentando detener un proceso, no lanzar una excepción Python KeyboardInterrupt.

Además, vea esto previamente respondido question.

Espero que esto ayude!

+0

Entonces, ¿por qué KeyboardInterrupt a través de Ctrl + C funciona en el shell pero no en Idle? – cssndrx

+0

Edité la publicación. ver los nuevos cambios – Sam

+0

No creo entender lo que estás diciendo ... ¿qué estás diciendo que Ctrl + C hace en inactividad? Además, Ctrl + C en el shell da como resultado una excepción KeyboardInterrupt – cssndrx

Cuestiones relacionadas