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 代码效率的方法
Jul 03 Python
用Python编写脚本使IE实现代理上网的教程
Apr 23 Python
Python中常见的数据类型小结
Aug 29 Python
python逐行读写txt文件的实例讲解
Apr 03 Python
基于python requests库中的代理实例讲解
May 07 Python
Django使用Mysql数据库已经存在的数据表方法
May 27 Python
Python在for循环中更改list值的方法【推荐】
Aug 17 Python
python绘制简单彩虹图
Nov 19 Python
windows 10 设定计划任务自动执行 python 脚本的方法
Sep 11 Python
pygame实现五子棋游戏
Oct 29 Python
如何搭建pytorch环境的方法步骤
May 06 Python
使用Python+Appuim 清理微信的方法
Jan 26 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
多文件上传的例子
2006/10/09 PHP
php和editplus正则表达式去除空白行
2015/04/17 PHP
php 计算两个时间相差的天数、小时数、分钟数、秒数详解及实例代码
2016/11/09 PHP
thinkphp 手机号和用户名同时登录
2017/01/20 PHP
thinkPHP简单导入和使用阿里云OSSsdk的方法
2017/03/15 PHP
laravel框架分组控制器和分组路由实现方法示例
2020/01/25 PHP
js获取location.href的参数实例代码
2013/08/02 Javascript
Javascript delete 引用类型对象
2013/11/01 Javascript
解决JQeury显示内容没有边距内容紧挨着浏览器边线
2013/12/20 Javascript
javascript实现图像循环明暗变化的方法
2015/02/25 Javascript
BootStrap selectpicker
2016/06/20 Javascript
JS实现新建文件夹功能
2017/06/17 Javascript
Vue作用域插槽slot-scope实例代码
2018/09/05 Javascript
详解JavaScript修改注册表的方法
2020/01/05 Javascript
Vue中watch、computed、updated三者的区别及用法
2020/07/27 Javascript
Python实现解析Bit Torrent种子文件内容的方法
2017/08/29 Python
python spyder中读取txt为图片的方法
2018/04/27 Python
python 按照固定长度分割字符串的方法小结
2018/04/30 Python
详解Python3 基本数据类型
2019/04/19 Python
Python实现的统计文章单词次数功能示例
2019/07/08 Python
python 使用socket传输图片视频等文件的实现方式
2019/08/07 Python
PyCharm License Activation激活码失效问题的解决方法(图文详解)
2020/03/12 Python
Python Opencv中用compareHist函数进行直方图比较对比图片
2020/04/07 Python
html table呈现个人简历以及单元格宽度失效的问题解决
2021/01/22 HTML / CSS
西尔斯百货官网:Sears
2016/09/06 全球购物
上海天奕面试题笔试题
2015/04/19 面试题
办公室经理岗位职责
2014/01/01 职场文书
社区交通安全实施方案
2014/03/22 职场文书
新学期国旗下演讲稿
2014/05/08 职场文书
客运企业隐患排查工作方案
2014/06/06 职场文书
花坛标语大全
2014/06/30 职场文书
欢迎家长标语
2014/10/08 职场文书
总经理检讨书范文
2015/02/16 职场文书
同学毕业留言寄语
2015/02/27 职场文书
贫民窟的百万富翁观后感
2015/06/09 职场文书
uniapp开发小程序的经验总结
2021/04/08 Javascript