在python中停止定时线程

时间:2012-12-25 12:16:47

标签: python multithreading

当主脚本被杀死时,我正试图在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()

3 个答案:

答案 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程序退出。

请注意,在此线程正在执行其工作的过程中,您仍然可能遇到问题。如果你想防止这种情况发生,那么让线程经常醒来检查它是否应该干净地退出。