zoukankan      html  css  js  c++  java
  • PYTHON 定时器简单封装,基于SCHED

    python fresher,轻拍。
    在写后台服务时经常会遇到很多定时器的场景,threading.Timer类每实例化一个定时器会有一个新线程去执行,在客户端使用倒是没有问题,如果是服务器端定时器数量多了会影响性能。通常的做法是一个线程按照指定精度发出Ticker,然后检查有没有设置定时器,由则触发;同时要提供SetTimer,KillTimer方法。常用的算法有基于小根堆,时间轮。

    本例采用py内置模块sched调度器,sched模块内部使用的优先级队列管理任务,性能未测。

    #!/usr/bin/env python3
    #-*- coding: utf-8 -*-
    
    import sched
    import time
    import threading
    
    
    '''
    定时器类,基于sched调度,独立线程服务
    '''
    class Timer(threading.Thread):
        '''初始化'''
        def __init__(self,interval=0.05):
            threading.Thread.__init__(self)
            self.__sch = sched.scheduler(time.time,time.sleep)
            self.__flag = True
            self.__min_interval = interval
    
        #overload
        def run(self):
            while self.__flag:
                self.__sch.run()
                time.sleep(self.__min_interval)
                continue
    
        #overload
        def Start(self):
            self.start()
    
        def SetTimer(self,interval,func,args):
            return self.__sch.enter(interval,0,func,args)
    
        def KillTimer(self,event):
            try:
                self.__sch.cancel(event)
            except ValueError as e:
                print("KillTimer err:",e)
            else:
                print("KillTimer unknow err")
    
    
        def Destroy(self):
            self.__flag=False
    
    if __name__ == "__main__":
        t=Timer()
        t.Start()
    
        def func(msg):
            print("timeout ", msg)
    
        e=t.SetTimer(1,func,("msg",))
        print("set timer",e)
        #t.KillTimer(e)
        t.Destroy()
    

    已知问题:定时器由单线程执行并触发执行,定时器函数的执行会由很大影响。

    if __name__ == "__main__":
        t=Timer()
        t.Start()
        def func(msg):
            print("timeout ", msg," now ",time.time())
            time.sleep(2)
    
        e = t.SetTimer(1, func, ("msg1",))
        e = t.SetTimer(1, func, ("msg2",))
    

    执行结果:

    timeout  msg1  now  1513819586.3577309
    timeout  msg2  now  1513819588.3586824
    

    func与定时器是同一线程执行,如果新开线程执行func对于耗时少的func又不划算;这点就体现出golang的优势,定时器触发后直接go func(msg),系统开销很小。

  • 相关阅读:
    POJ 1862 Stripies (简单贪心)
    HDU 2181 哈密顿绕行世界问题(DFS)
    POJ 3262 Protecting the Flowers (贪心)
    Aizu 2249 Road Construction (最短路 SPFA)
    POJ 3484 Showstopper(二分)
    HDU 6235 2017-CCPC-哈尔滨站 Permutation(简单模拟)
    IDEA常用插件
    解决IDEA插件加载失败
    解决zsh无法使用maven
    Linux安装Maven
  • 原文地址:https://www.cnblogs.com/cqvoip/p/8078651.html
Copyright © 2011-2022 走看看