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中的cookielib模拟登录网站
Apr 09 Python
使用python爬虫实现网络股票信息爬取的demo
Jan 05 Python
浅析Python pandas模块输出每行中间省略号问题
Jul 03 Python
Windows下python3.7安装教程
Jul 31 Python
python实时获取外部程序输出结果的方法
Jan 12 Python
Python3 合并二叉树的实现
Sep 30 Python
Python集合基本概念与相关操作实例分析
Oct 30 Python
Python字节单位转换实例
Dec 05 Python
Python json读写方式和字典相互转化
Apr 18 Python
使用tensorflow进行音乐类型的分类
Aug 14 Python
详解Python中如何将数据存储为json格式的文件
Nov 18 Python
Python基于unittest实现测试用例执行
Nov 25 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
修改apache配置文件去除thinkphp url中的index.php
2014/01/17 PHP
PHP fopen()和 file_get_contents()应用与差异介绍
2014/03/19 PHP
laravel 4安装及入门图文教程
2014/10/29 PHP
PHP基于session.upload_progress 实现文件上传进度显示功能详解
2019/08/09 PHP
Laravel5.5 视图 - 创建视图和数据传递示例
2019/10/21 PHP
jQuery 选择器理解
2010/03/16 Javascript
js常用排序实现代码
2010/12/28 Javascript
30个让人兴奋的视差滚动(Parallax Scrolling)效果网站
2012/03/04 Javascript
Jquery封装tab自动切换效果的具体实现
2013/07/13 Javascript
js QQ客服悬浮效果实现代码
2014/12/12 Javascript
arguments对象验证函数的参数是否合法
2015/06/26 Javascript
angular.bind使用心得
2015/10/26 Javascript
js中flexible.js实现淘宝弹性布局方案
2020/06/23 Javascript
Javascript的无new构建实例详解
2016/05/15 Javascript
JavaScript中Array的实用操作技巧分享
2016/09/11 Javascript
vue.js指令v-model使用方法
2017/03/20 Javascript
javascript 中iframe高度自适应(同域)实例详解
2017/05/16 Javascript
Vue2 Vue-cli中使用Typescript的配置详解
2017/07/24 Javascript
vue添加class样式实例讲解
2019/02/12 Javascript
es6中reduce的基本使用方法
2019/09/10 Javascript
VUE项目初建和常见问题总结
2019/09/12 Javascript
vue实现简易图片左右旋转,上一张,下一张组件案例
2020/07/31 Javascript
python中的sort方法使用详解
2014/07/25 Python
Python3基础之基本数据类型概述
2014/08/13 Python
跟老齐学Python之从if开始语句的征程
2014/09/14 Python
python web框架学习笔记
2016/05/03 Python
Python实现在某个数组中查找一个值的算法示例
2018/06/27 Python
python实现朴素贝叶斯算法
2018/11/19 Python
python属于哪种语言
2020/08/16 Python
Python命令行参数argv和argparse该如何使用
2021/02/08 Python
HTML 5 标签、属性、事件及浏览器兼容性速查表 附打包下载
2012/10/20 HTML / CSS
Bose加拿大官方网站:美国知名音响品牌
2019/03/21 全球购物
英国领先的游戏零售商:GAME
2019/09/24 全球购物
2014年个人债务授权委托书范本
2014/09/22 职场文书
初一年级组工作总结
2015/08/12 职场文书
创业计划书之校园超市
2019/09/12 职场文书