在 python 中中断/中断 time.sleep()

问题描述 投票:0回答:7

我需要使用 ctrl c 来中断 time.sleep() 。

While 1:
    time.sleep(60)

在上面的代码中,当控件进入 time.sleep 函数时,Python 需要经过整整 60 秒才能处理 CTRL C

有什么优雅的方法可以做到这一点吗?这样即使控制处于 time.sleep 功能我也可以中断

编辑

我正在旧版实现上测试它,该实现在 Windows 2000 上使用 python 2.2,这导致了所有麻烦。如果我使用更高版本的 python CTRL C 会中断 sleep() 。我通过在 for 循环中调用 sleep(1) 进行了快速破解。这暂时解决了我的问题

python
7个回答
214
投票

正确的答案是使用 python stdlib 的 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 signal.signal(signal.SIGTERM, quit) signal.signal(signal.SIGINT, quit) signal.signal(signal.SIGHUP, quit) main()

当信号处理程序调用 
exit.set()

时,主线程的
wait()
调用将

立即

被中断。
现在,您可以使用 
Event 来表示还有更多工作要做等。但在这种情况下,它具有双重作用,作为我们想要退出的方便指示符(例如 while not exit.is_set()

部分。)

您还可以选择在 
while
 循环之后放置任何清理代码。

不确定这段代码的意义是什么 - 但如果有必要,请使用更短的 sleep() 间隔并在其周围放置一个 for 循环:

for i in range(60): sleep(1)

16
投票
使用 try..except 捕获

KeyboardInterrupt

异常是直接的
    

当用户按下中断键 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()

7
投票
这样,您就可以在收到键盘中断时做任何您想做的事情。

最优雅的解决方案当然是

threading.Event

,但如果您只需要快速破解,此代码效果很好:

4
投票
import time def main(): print("It’s time !") if __name__ == "__main__": print("press ctrl-c to stop") loop_forever = True while loop_forever: main() try: time.sleep(60) except KeyboardInterrupt: loop_forever = False


我在 Linux 下使用 python 版本 2.5、2.6、3 尝试了你的代码,当按下 CTRL-C 时,所有代码都会抛出“KeyboardInterrupt”异常。

也许某些异常处理捕获了中断,或者您的问题是这样的:

2
投票

基于@Andreas Jung 的回答

for i in range(360): try: sleep(1) except KeyboardInterrupt: sys.exit(0)

1
投票

我想我会把这个扔进去。
import time


def sleep(seconds):
    for i in range(seconds):
        try:
            time.sleep(1)
        except KeyboardInterrupt:
            print("Oh! You have sent a Keyboard Interrupt to me.\nBye, Bye")
            break


sleep(60)

0
投票

© www.soinside.com 2019 - 2024. All rights reserved.