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将mdb数据库文件导入postgresql数据库示例
Feb 17 Python
Python中的测试模块unittest和doctest的使用教程
Apr 14 Python
用Python脚本来删除指定容量以上的文件的教程
May 04 Python
python xlsxwriter库生成图表的应用示例
Mar 16 Python
Python判断两个list是否是父子集关系的实例
May 04 Python
python机器学习之KNN分类算法
Aug 29 Python
Python IDE Pycharm中的快捷键列表用法
Aug 08 Python
Python二维数组实现求出3*3矩阵对角线元素的和示例
Nov 29 Python
python中threading开启关闭线程操作
May 02 Python
python使用openpyxl操作excel的方法步骤
May 28 Python
keras实现VGG16方式(预测一张图片)
Jul 07 Python
Python3中的tuple函数知识点讲解
Jan 03 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
基于qmail的完整WEBMAIL解决方案安装详解
2006/10/09 PHP
php实现求相对时间函数
2015/06/15 PHP
php 问卷调查结果统计
2015/10/08 PHP
PHP使用PHPExcel实现批量上传到数据库的方法
2017/06/08 PHP
Laravel利用gulp如何构建前端资源详解
2018/06/03 PHP
PHP中define() 与 const定义常量的区别详解
2019/06/25 PHP
php将字符串转换为数组实例讲解
2020/05/05 PHP
PHP数组实际占用内存大小原理解析
2020/12/11 PHP
javascript之锁定表格栏位
2007/06/29 Javascript
js调用flash的效果代码
2008/04/26 Javascript
js和php如何获取当前url的内容
2013/09/22 Javascript
javascript静态页面传值的三种方法分享
2013/11/12 Javascript
js计算两个时间之间天数差的实例代码
2013/11/19 Javascript
js光标定位文本框回车表单提交问题的解决方法
2015/05/11 Javascript
JavaScript  cookie 跨域访问之广告推广
2016/04/20 Javascript
大白话讲解JavaScript的Promise
2017/04/06 Javascript
Javascript实现信息滚动效果
2017/05/18 Javascript
Angularjs cookie 操作实例详解
2017/09/27 Javascript
Bootstrap Table中的多选框删除功能
2018/07/15 Javascript
Vue.js组件高级特性实例详解
2018/12/24 Javascript
vue history 模式打包部署在域名的二级目录的配置指南
2019/07/02 Javascript
在Python中操作字符串之replace()方法的使用
2015/05/19 Python
Python字符串格式化
2015/06/15 Python
学习python之编写简单乘法口诀表实现代码
2016/02/27 Python
python开发利器之ulipad的使用实践
2017/03/16 Python
Python代码实现删除一个list里面重复元素的方法
2019/04/02 Python
将pip源更换到国内镜像的详细步骤
2019/04/07 Python
python 利用pywifi模块实现连接网络破解wifi密码实时监控网络
2019/09/16 Python
python numpy存取文件的方式
2020/04/01 Python
CSS3打造百度贴吧的3D翻牌效果示例
2017/01/04 HTML / CSS
Dr. Martens马汀博士法国官网:马丁靴鼻祖
2020/01/15 全球购物
大学生新学期计划书
2014/04/28 职场文书
法制宣传教育方案
2014/05/09 职场文书
基层工作经验证明样本
2014/11/16 职场文书
期末个人总结范文
2015/02/13 职场文书
活着观后感
2015/06/03 职场文书