在Python中打断time.sleep()
我想在使用time.sleep()的时候,按Ctrl+C可以中断它。
While 1:
time.sleep(60)
在上面的代码中,当程序进入time.sleep这个函数时,需要整整60秒才能让Python处理Ctrl+C的中断。
有没有什么更好的方法,可以在time.sleep函数运行的时候就能中断它呢?
编辑
我是在一个老旧的系统上测试的,那个系统用的是Python 2.2,运行在Windows 2000上,这导致了很多麻烦。如果我用的是更新版本的Python,按Ctrl+C就能中断sleep()了。我临时用一个小技巧解决了这个问题,就是在一个循环里每次调用sleep(1),这样暂时解决了我的问题。
7 个回答
当用户按下中断键 Ctrl-C 时,就会出现一个叫做 KeyboardInterrupt 的异常。在 Python 中,这个异常是由一个叫 SIGINT 的信号引起的。这意味着,你可以使用信号模块来处理这个异常,按照你想要的方式来应对:
import signal
def handler(signum, frame):
print("do whatever, like call thread.interrupt_main()")
signal.signal(signal.SIGINT, handler)
print("Waiting for SIGINT...")
signal.pause()
这样一来,当你收到键盘中断时,就可以做任何你想做的事情。
正确的做法是使用Python标准库中的threading.Event
。
当然,你可以把睡眠时间调得很短,这样就能在很短的时间内醒来,但如果你真的想每60秒运行一次循环呢?那你就得花更多的时间去判断是不是该运行了,还是继续睡觉。而且,你仍然是在阻塞,只不过时间短一些。相比之下,threading.Event
就好用多了:
from threading import Event
exit = Event()
def main():
while not exit.is_set():
do_my_thing()
exit.wait(60)
print("All done!")
# perform any cleanup here
def quit(signo, _frame):
print("Interrupted by %d, shutting down" % signo)
exit.set()
if __name__ == '__main__':
import signal
for sig in ('TERM', 'HUP', 'INT'):
signal.signal(getattr(signal, 'SIG'+sig), quit);
main()
当信号处理器调用exit.set()
时,主线程的wait()
调用会立即被打断。
现在,你可以使用Event
来表示还有更多工作要做等等。但在这种情况下,它还可以方便地指示我们想要退出(比如while not exit.is_set()
这一部分)。
你还可以选择在while
循环后放置任何清理代码。
我不太明白这段代码的意思,不过如果需要的话,可以把 sleep() 的时间缩短一点,然后在它外面加个 for 循环:
for i in range(60):
sleep(1)
用 try..except 来捕捉 KeyboardInterrupt 异常是很简单的。