[英]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.