python sched取消线程

时间:2017-06-11 11:58:23

标签: python multithreading scheduled-tasks

我使用Python 3.4和3.6。我将sched.scheduler用于典型的1小时间隔的未来事件。我在threading.Thread中运行调度程序,因此它是非阻塞的。

我运行第二个threading.Thread监视每个5秒的全局参数_busy。在全局级别reset()可以将此参数设置为False。

开启"重置",取消调度程序中的所有剩余事件。 最后,我在两个线程上使用.join()作为清理。 但是,具有调度程序的线程在退出之前等待下一个(已取消)调度程序事件。这可能是在那个小时的间隔之后。

如何强制sched.scheduler更新"在取消所有事件之后,它是否已经完成并且调度程序线程退出了?

import threading
import time
import sched
import winsound

def ScheduleSound(*args):
    ''' Beep as demo for slowscan '''
    winsound.Beep(args[-1], 500)

class SlowScanSchedule(object):
    '''
        Main interface for slow scan schedule i.e.
        - read and store content of ini-file
        - add actions to schedule
        - start schedule and schedule monitor thread
        Example:
            eggs = SlowScanSchedule("slowscan01.ini")
            eggs.start()
            eggs.schedule.queue
            eggs._monitorthread.isAlive()
            eggs._schedulethread.isAlive()
            eggs.reset() # abort schedule ... takes some time
    '''
    def __init__(self, filename, **kwargs):
        self.schedule = sched.scheduler(time.time, time.sleep)
        # self.slowscan = omiconfig.IniFile(filename=filename)
        # demo entries for starttime and schedule
        self.timestart = time.mktime(time.localtime())
        self.slowscan = [[10, 7, 1500], [10, 42, 1500], [10, 8, 1500], \
                    [300, 34, 1500], [300, 9, 1500], [300, 67, 1500]]
        self._monitorthread = None
        self._schedulethread = None
        self._busy = False
        # removed all logging for demo
        self._update()
    def _update(self):
        '''fill scheduler'''
        self.reset() # reset scheduled tasks
        previousdelay = 0.0
        for exposevalues in self.slowscan:
            self._add(previousdelay, ScheduleSound, *exposevalues)
            previousdelay += exposevalues[0]
    def _add(self, secondsdelay, executeobject, *executeargs):
        '''Auxiliary: add actions to schedule'''
        self.schedule.enterabs(self.timestart + secondsdelay,
                               1,
                               executeobject,
                               argument=(executeargs))
    def reset(self):
        '''Stop thread with scheduler'''
        self._busy = False
        if self._monitorthread is not None:
            self._monitorthread.join()
            self._schedulethread.join()
        self._monitorthread = None
        self._schedulethread = None
    def start(self):
        '''Start schedule and monitor threads'''
        if self._monitorthread is not None:
            try:
                self.reset()
            except:
                self._monitorthread = None
                self._schedulethread = None
        self._schedulethread = ScheduleThread(self.schedule)
        self._monitorthread = MonitorThread(self)

class MonitorThread(threading.Thread):
    '''Auxiliary object for scheduler monitor inside thread'''
    def __init__(self, monitor):
        '''Create and start thread for scheduler monitor'''
        threading.Thread.__init__(self)
        self._lock = threading.Lock()
        self.monitor = monitor
        self.monitor._busy = True
        self.start()
    def run(self):
        '''Non-blocking thread that monitors global _busy and schedule'''
        while self.monitor._busy and not self.monitor.schedule.empty():
            time.sleep(5)
        self._lock.acquire()
        while not self.monitor.schedule.empty():
            self.monitor.schedule.cancel(self.monitor.schedule.queue[-1])
        self._lock.release()
        self.monitor._busy = False

class ScheduleThread(threading.Thread):
    '''Auxiliary object for scheduler inside thread'''
    def __init__(self, schedule, **kwargs):
        threading.Thread.__init__(self)
        self.schedule = schedule
        self.start()
    def run(self):
        self.schedule.run(blocking=True)

0 个答案:

没有答案