繁体   English   中英

Python - 取消计时器线程

[英]Python - Cancel timer thread

我正在尝试创建一个在我的主脚本后台运行在计时器上的方法:

def hello_world(self):
        print 'Hello!'
        threading.Timer(2,hello_world).start()

if __name__ == "__main__":
    try:
        hello_world()
    except KeyboardInterrupt:
        print '\nGoodbye!'

当我尝试键盘中断我的脚本时收到此消息:

Exception KeyboardInterrupt in <module 'threading' from '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py'> ignored

如何关闭线程以便我可以干净地退出应用程序?

为了详细说明Aphex的答案,主线程不可能捕获KeyboardInterrupt信号,除非你有非常快的手指。 主线程几乎立即退出! 尝试这个:

import threading

def hello_world():
        print 'Hello!'
        threading.Timer(2,hello_world).start()

if __name__ == "__main__":
    try:
        hello_world()
    except KeyboardInterrupt:
        print '\nGoodbye!'
    print "main thread exited"

更一般地说,我不建议像这样使用自调用计时器,因为它会创建大量线程。 只需创建一个线程并在其中调用time.sleep

但是,只要你保持主线程运行,你似乎能够在里面捕获KeyboardInterrupt 然后诀窍是使线程成为主线程退出时退出的daemon线程。

import threading
import time

def hello_world():
    while(True):
        print 'Hello!'
        time.sleep(2)

if __name__ == "__main__":
    hw_thread = threading.Thread(target = hello_world)
    hw_thread.daemon = True
    hw_thread.start()
    try:
        time.sleep(1000)
    except KeyboardInterrupt:
        print '\nGoodbye!'

这会在1000秒后自动退出 - 如果您愿意,可以使该数字更大。 您也可以使用忙循环重复睡眠呼叫,但我真的没有看到这一点。

您只需将Timer线程设置为daemon

def hello_world(self):
    print 'Hello!'
    t = threading.Timer(2,hello_world)
    t.daemon = True
    t.start()

这将导致它在主线程退出时退出,例如由于KeyboardInterrupt

当只剩下的线程是daemon线程时, daemon设置会导致整个程序退出。

尝试重新引发KeyboardInterrupt异常: http//effbot.org/zone/stupid-exceptions-keyboardinterrupt.htm

这仍然可能不起作用; 你有可能遇到这个警告

线程与中断奇怪地交互:KeyboardInterrupt异常将由任意线程接收。 (当信号模块可用时,中断始终转到主线程。)

简而言之,您无法确定KeyboardInterrupt是否会转到主线程。 要解决此问题,您可能需要查看signal模块。

编辑:取消线程的一种更优雅的方法是拥有线程所看到的共享变量,如果它变为false退出。 然后,如果要从主线程中终止线程,则将变量设置为false

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM