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


Posted in Python onMarch 30, 2014

单线程实现多个定时器

NewTimer.py

#!/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()
Python 相关文章推荐
Python解析nginx日志文件
May 11 Python
python交互式图形编程实例(一)
Nov 17 Python
浅谈Python Opencv中gamma变换的使用详解
Apr 02 Python
详解Django中类视图使用装饰器的方式
Aug 12 Python
django中forms组件的使用与注意
Jul 08 Python
django使用haystack调用Elasticsearch实现索引搜索
Jul 24 Python
使用PyTorch将文件夹下的图片分为训练集和验证集实例
Jan 08 Python
Python 如何实现访问者模式
Jul 28 Python
python破解同事的压缩包密码
Oct 14 Python
MoviePy常用剪辑类及Python视频剪辑自动化
Dec 18 Python
教你如何使用Python下载B站视频的详细教程
Apr 29 Python
Pandas数据类型之category的用法
Jun 28 Python
python实现猜数字游戏(无重复数字)示例分享
Mar 29 #Python
使用python实现扫描端口示例
Mar 29 #Python
Python Trie树实现字典排序
Mar 28 #Python
python实现探测socket和web服务示例
Mar 28 #Python
python实现目录树生成示例
Mar 28 #Python
python改变日志(logging)存放位置的示例
Mar 27 #Python
使用python删除nginx缓存文件示例(python文件操作)
Mar 26 #Python
You might like
PHP单例模式详解及实例代码
2016/12/21 PHP
js word表格动态添加代码
2010/06/07 Javascript
前台js改变Session的值(用ajax实现)
2012/12/28 Javascript
jquery隔行换色效果实现方法
2015/01/15 Javascript
分享五个有用的jquery小技巧
2015/10/08 Javascript
js图片轮播手动切换效果
2015/11/10 Javascript
动态设置form表单的action属性的值的简单方法
2016/05/25 Javascript
node.js版本管理工具n无效的原理和解决方法
2016/11/24 Javascript
第一次接触神奇的前端框架vue.js
2016/12/01 Javascript
node.js+jQuery实现用户登录注册AJAX交互
2017/04/28 jQuery
详解angular 中的自定义指令之详解API
2017/06/20 Javascript
jquery.param()实现数组或对象的序列化方法
2018/10/08 jQuery
vue如何实现自定义底部菜单栏
2019/07/01 Javascript
jQuery中DOM常见操作实例小结
2019/08/01 jQuery
layui 上传文件_批量导入数据UI的方法
2019/09/23 Javascript
jQuery使用hide()、toggle()函数实现相机品牌展示隐藏功能
2021/01/29 jQuery
详解Python中的装饰器、闭包和functools的教程
2015/04/02 Python
selenium+python实现1688网站验证码图片的截取功能
2018/08/14 Python
PIL图像处理模块paste方法简单使用详解
2019/07/17 Python
Python利用神经网络解决非线性回归问题实例详解
2019/07/19 Python
django 环境变量配置过程详解
2019/08/06 Python
python爬虫 2019中国好声音评论爬取过程解析
2019/08/26 Python
Python Opencv 通过轨迹(跟踪)栏实现更改整张图像的背景颜色
2020/03/09 Python
keras 指定程序在某块卡上训练实例
2020/06/22 Python
Css3+Js制作漂亮时钟(附源码)
2013/04/24 HTML / CSS
Clearly澳大利亚:购买眼镜、太阳镜和隐形眼镜
2018/04/26 全球购物
乌克兰电子和家用电器商店:Foxtrot
2019/07/23 全球购物
应届生船舶驾驶求职信
2013/10/19 职场文书
全民健身日活动方案
2014/01/29 职场文书
初三学生评语大全
2014/04/24 职场文书
初中优秀班集体申报材料
2014/05/01 职场文书
给老师的一封感谢信
2015/01/20 职场文书
六五普法心得体会2016
2016/01/21 职场文书
火锅店的开业营销方案范本!
2019/07/05 职场文书
Java elasticsearch安装以及部署教程
2021/06/28 Java/Android
vue如何清除浏览器历史栈
2022/05/25 Vue.js