源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

python单线程实现多个定时器示例

  • 时间:2021-01-03 05:09 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:python单线程实现多个定时器示例
单线程实现多个定时器 NewTimer.py
[u]复制代码[/u] 代码如下:
#!/usr/bin/env python from heapq import * from threading import Timer import threading import uuid import time import datetime import sys import math global TimerStamp global TimerTimes class CancelFail(Exception):     pass class Slot(object):     def __init__(self, period=0, interval=1, function=None, args=[], kwargs={}):         self.period = period         self.pc = 0         self.interval = interval         self.fire = 0         self.id = uuid.uuid1()         self.function = function         self.args = args         self.kwargs = kwargs #system resolution millisecond         class NewTimer(object):     #set enough time make thread sleep, when NewTimer empty set enoug time, too     #make sure sum of your timer call back function execute time shorter than resolution     #todo use a worker thread to operate timer call back function     def __init__(self, resolution=1000):         global TimerStamp         TimerStamp = int(time.time() * 1000)         self.nofire = sys.maxint #next fire time interval         self.firestamp = self.nofire + TimerStamp         self.resolution = resolution# 1s         self.lock = threading.RLock()         self.wait = dict()         self.ready = dict()         self._start()     """ private operate ready list """     def _addToReadyList(self, slot, firestamp):         box = dict( [ (slot.id, slot)])         if not self.ready.has_key( firestamp ):             self.ready.update( [(firestamp, box)] )         else:             boxs = self.ready.get(firestamp)             boxs.update( box )     def _delFromReadyList(self, slot):         boxs = self.ready.get(slot.fire)         try:             box = boxs.pop(slot.id)             if not boxs:                 self.ready.pop(slot.fire)         except (AttributeError, KeyError):             raise CancelFail     """ inside """     def _start(self):         global TimerStamp         try:             self.firestamp = sorted( self.ready.keys() )[0]             stamp = float((TimerStamp + self.firestamp - int(time.time()*1000)))/1000         except IndexError:             self.firestamp = self.nofire             stamp = self.nofire         try:             self.timer.cancel()         except AttributeError:             pass         self.timer = Timer( stamp, self.hander)         self.timer.start()     def hander(self, *args, **kwargs):         """ find time arrive slot, do it function """         self.lock.acquire()         try:             boxs = self.ready.pop( self.firestamp )             slots = boxs.values()         except KeyError:             slots = []         for slot in slots:             if slot.period:                 slot.pc += 1                 if slot.pc != slot.period:                     slot.fire = slot.interval + slot.fire                     self._addToReadyList(slot, slot.fire)             elif slot.period == -1:                 slot.fire = slot.interval + slot.fire                 self._addToReadyList(slot, slot.fire)         """ """         self._start()         self.lock.release()         for slot in slots:             try:                 slot.function(slot.args, slot.kwargs)             except Exception:                 print "slot id %s, timer function fail" % slot.id     """ operate new timer manager itself """     def stop(self):         self.timer.cancel()     """ new timer manager """     def add(self, period=0, interval=1, function=None, args=[], kwargs={}):         """         period: one time = 0, times = >0, always = -1         interval: timer fire relative TimerReference         function: when timer fire, call back function         args,kwargs: callback function args         """         interval = int(interval) * self.resolution#seconds         if interval < self.resolution:             interval = self.resolution         slot = Slot( period, interval, function, *args, **kwargs )         box = dict([(slot.id, slot)])         self.wait.update(box)         return slot     def remove(self, slot):         if isinstance(slot, Slot):             self.cancel(slot)             try:                 self.wait.pop(slot.id)             except KeyError:                 print "wait dict not has the cancel timer"     """ timer api """     def reset(self, slot):         if isinstance(slot, Slot):             self.cancel(slot)             slot.pc = 0             self.start(slot)     def start(self, slot):         def NewTimerStamp(timebase, resolution):             nowoffset = int(time.time() * 1000) - timebase             if nowoffset % resolution < resolution / 10:                 currentstamp =  nowoffset / resolution             else:                 currentstamp = (nowoffset + resolution - 1) / resolution             return currentstamp * 1000         global TimerStamp         if isinstance(slot, Slot):             firestamp = slot.interval + NewTimerStamp(TimerStamp, self.resolution)             slot.fire = firestamp             self.lock.acquire()             self._addToReadyList(slot, firestamp)             if self.firestamp > slot.fire:                 self._start()             self.lock.release()     def cancel(self, slot):         if isinstance(slot, Slot):             try:                  self.lock.acquire()                 self._delFromReadyList(slot)                 self._start()                 self.lock.release()             except CancelFail:                 self.lock.release() def hello( *args, **kargs):     print args[0], datetime.datetime.now() if __name__ == "__main__":     print "start test timer", datetime.datetime.now()     nt = NewTimer(500)     t0 = nt.add( -1, 5, hello, [0])     t1 = nt.add( 4, 7, hello, [1])     t2 = nt.add( 1, 3, hello, [2])#     t3 = nt.add( 1, 4, hello, [3])#     t4 = nt.add( 4, 5, hello, [4])     t5 = nt.add( 12, 5, hello, [5])#     t6 = nt.add( 9, 7, hello, [6])     t7 = nt.add( 1, 8, hello, [7])#     t8 = nt.add( 40, 1, hello, [8])     nt.start( t0 )     nt.start( t1 )     nt.start( t2 )#     nt.start( t3 )#     nt.start( t4 )     nt.start( t5 )#     nt.start( t6 )     nt.start( t7 )#     nt.start( t8 )     nt.cancel(t2)     nt.cancel(t3)     nt.remove(t5)     nt.remove(t3)     time.sleep(3)     nt.start(t2)     nt.cancel(t8)     time.sleep(300)     nt.stop()     print "finish test timer", datetime.datetime.now()
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部