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 Mysql自动备份脚本
Jul 14 Python
Python使用Flask框架同时上传多个文件的方法
Mar 21 Python
Python函数式编程指南(一):函数式编程概述
Jun 24 Python
python高手之路python处理excel文件(方法汇总)
Jan 07 Python
Python打印“菱形”星号代码方法
Feb 05 Python
设置python3为默认python的方法
Oct 31 Python
详解利用Python scipy.signal.filtfilt() 实现信号滤波
Jun 05 Python
python实现在函数中修改变量值的方法
Jul 16 Python
django 邮件发送模块smtp使用详解
Jul 22 Python
Pandas时间序列重采样(resample)方法中closed、label的作用详解
Dec 10 Python
Python中的With语句的使用及原理
Jul 29 Python
Python字符串三种格式化输出
Sep 17 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在字符断点处截断文字的实现代码
2011/04/21 PHP
php定时计划任务的实现方法详解
2013/06/06 PHP
php中数字、字符与对象判断函数用法实例
2014/11/26 PHP
DEDECMS首页调用图片集里的多张图片
2015/06/05 PHP
分享PHP守护进程类
2015/12/30 PHP
使用Apache的rewrite
2021/03/09 Servers
Jquery命名冲突解决的五种方案分享
2012/03/16 Javascript
JavaScript创建对象的写法
2013/08/29 Javascript
JS如何实现文本框随文本的长度而增长
2015/07/30 Javascript
JavaScript重载函数实例剖析
2016/05/13 Javascript
js仿iphone秒表功能 计算平均数
2017/01/11 Javascript
JavaScript禁止微信浏览器下拉回弹效果
2017/05/16 Javascript
jQuery层级选择器_动力节点节点Java学院整理
2017/07/04 jQuery
通过命令行生成vue项目框架的方法
2017/07/12 Javascript
微信小程序 转发功能的实现
2017/08/04 Javascript
Babel 入门教程学习笔记
2018/06/13 Javascript
es6函数之严格模式用法实例分析
2020/03/17 Javascript
React+EggJs实现断点续传的示例代码
2020/07/07 Javascript
原生JavaScript实现随机点名表
2021/01/14 Javascript
django允许外部访问的实例讲解
2018/05/14 Python
使用Django连接Mysql数据库步骤
2019/01/15 Python
python学生管理系统开发
2019/01/30 Python
彪马英国官网:PUMA英国
2019/02/11 全球购物
美国巧克力喷泉品牌:Sephra
2019/05/05 全球购物
北京华建集团SQL面试题
2014/06/03 面试题
城建学院毕业生自荐信
2014/01/31 职场文书
《蜗牛》教学反思
2014/02/18 职场文书
2014年五四青年节活动策划书
2014/04/22 职场文书
主题教育活动总结
2014/05/05 职场文书
森林病虫害防治方案
2014/06/02 职场文书
酒店圣诞节活动总结
2015/05/06 职场文书
2015年暑期见闻
2015/07/14 职场文书
护理自荐信
2019/05/14 职场文书
关于Python OS模块常用文件/目录函数详解
2021/07/01 Python
关于JavaScript轮播图的实现
2021/11/20 Javascript
「Manga Time Kirara MAX」2022年5月号封面公开
2022/03/21 日漫