当主脚本被杀死时,我正试图在python中停止一个线程。但是由于线程每小时启动一次如何立即停止线程?
def interval():
###the actual work being done here###
try:
threading.Timer(3600, interval).start()
except (KeyboardInterrupt, SystemExit):
print "Exiting"
cleanup_stop_interval();
sys.exit()
interval()
答案 0 :(得分:2)
杀死这样的线程是一个坏主意,因为它可以
正确处理这个问题的方法是有一个exit_request标志,每个线程定期检查一次是否有时间让他退出,并等待它退出使用join()
答案 1 :(得分:2)
您可以考虑在此使用sched.scheduler
代替threading.Timer
。需要注意一些差异:
sched.scheduler
运行主进程中的所有内容,而不是
线程。delay
秒,那么
当前对interval
的调用之后,计划事件将开始
完成。 threading.Timer
的工作方式不同 - 如果工作完成的话
interval
需要超过一个小时,不止一个线程会运行
同时interval
。我猜你真的不希望同时运行多个interval
,因此sched.scheduler
可能比threading.Timer
更合适。
import timeit
import sched
import time
import logging
import sys
logger = logging.getLogger(__name__)
logging.basicConfig(level = logging.DEBUG,
format = '%(threadName)s: %(asctime)s: %(message)s',
datefmt = '%H:%M:%S')
schedule = sched.scheduler(timeit.default_timer, time.sleep)
delay = 5 # change to 3600 to schedule event in 1 hour
def interval():
logger.info('All work and no play makes Jack a dull boy.')
schedule.enter(delay = delay, priority = 1, action = interval, argument = ())
# Uncomment this to see how scheduled events are delayed if interval takes a
# long time.
# time.sleep(10)
schedule.enter(delay = 0, priority = 1, action = interval, argument = ())
try:
schedule.run()
except (KeyboardInterrupt, SystemExit):
print('Exiting')
sys.exit()
答案 2 :(得分:0)
您无法阻止来自其他线程的线程。您可能想要的是使线程成为守护程序线程,这意味着即使线程仍处于活动状态,进程也会退出:
http://docs.python.org/2/library/threading.html#threading.Thread.daemon
守护程序
一个布尔值,指示此线程是否为守护程序线程(True)或不是(False)。必须在调用start()之前设置它,否则引发RuntimeError。它的初始值继承自创建线程;主线程不是守护程序线程,因此在主线程中创建的所有线程都默认为daemon = False。
当没有剩下活着的非守护程序线程时,整个Python程序退出。
请注意,在此线程正在执行其工作的过程中,您仍然可能遇到问题。如果你想防止这种情况发生,那么让线程经常醒来检查它是否应该干净地退出。