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

Anu*_*nuj 46 python

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

While 1:
    time.sleep(60)
Run Code Online (Sandbox Code Playgroud)

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

有没有优雅的方式来做到这一点.这样我即使在控制时间内也可以中断.睡眠功能

编辑

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

tho*_*nic 94

正确的答案是使用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
    for sig in ('TERM', 'HUP', 'INT'):
        signal.signal(getattr(signal, 'SIG'+sig), quit);

    main()
Run Code Online (Sandbox Code Playgroud)

当信号处理程序调用时exit.set(),主线程的wait()调用将立即被中断.

现在,你可以使用一个Event来表示还有更多的工作要做,等等.但是在这种情况下,它确实是双重任务,作为我们想要退出的方便指标(例如,while not exit.is_set()部分).

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

  • 注意:在调用`exit.set()`之后,除非事件调用对象`exit.clear()`,否则`exit.wait()`调用将不再对事件对象`exit`起作用,请参考:[threading ::事件对象](https://docs.python.org/2/library/threading.html#event-objects) (2认同)
  • @travc 还应该注意的是 time.monotonic() 应该比 time.time() 更受欢迎。当调整/更改系统时钟时, time.time() 的使用会中断计时。 (2认同)
  • 这很漂亮。 (2认同)
  • 我想让这个工作,但它仍然在 ctrl-C 之后等待 60 秒,然后才为我退出。视窗Python 3.9 (2认同)

小智 10

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

for i in range(60):
   sleep(1)
Run Code Online (Sandbox Code Playgroud)

使用try..except 捕获KeyboardInterrupt异常非常简单

  • 这种反复尝试某件事的方法称为“轮询”。应尽可能避免这种情况,因为它通常会导致 CPU 资源的浪费。系统提供替代机制,例如@thorn_nic 使用的机制。它们非常高效,因为它们在本质上利用了特殊的硬件指令和中断。 (3认同)
  • 这可以扩展为更快的反应:对于 i in range(sec/0.1): sleep(0.1) (2认同)
  • 这可能适用于他的天真的例子,但在很多情况下,人们不能只是简单地更快地进行轮询。 (2认同)
  • 这是一个黑客行为。请参阅@thom_nic 的正确答案。 (2认同)

Pie*_*Sys 9

当用户按下中断键Ctrl-C时,会引发KeyboardInterrupt异常.在python中,这是从SIGINT信号转换而来的.这意味着,您可以使用信号模块处理它:

import signal

def handler(signum, frame):
    print "do whatever, like call thread.interrupt_main()"

signal.signal(signal.SIGINT, handler)

while 1:
    time.sleep(forever)
Run Code Online (Sandbox Code Playgroud)

这样,您可以在收到键盘中断时执行任何操作.

  • 中断仅在从睡眠中唤醒后处理.. :( (18认同)
  • 这仅适用于只有一个主线程的情况。如果您启动了其他线程,信号处理程序将不会处理其他正在休眠的线程。 (2认同)