python单线程实现多个定时器示例
单线程实现多个定时器
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 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 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()

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Lösung für Erlaubnisprobleme beim Betrachten der Python -Version in Linux Terminal Wenn Sie versuchen, die Python -Version in Linux Terminal anzuzeigen, geben Sie Python ein ...

Bei der Verwendung von Pythons Pandas -Bibliothek ist das Kopieren von ganzen Spalten zwischen zwei Datenrahmen mit unterschiedlichen Strukturen ein häufiges Problem. Angenommen, wir haben zwei Daten ...

Wie erstellt in Python ein Objekt dynamisch über eine Zeichenfolge und ruft seine Methoden auf? Dies ist eine häufige Programmieranforderung, insbesondere wenn sie konfiguriert oder ausgeführt werden muss ...

Wie hört Uvicorn kontinuierlich auf HTTP -Anfragen an? Uvicorn ist ein leichter Webserver, der auf ASGI basiert. Eine seiner Kernfunktionen ist es, auf HTTP -Anfragen zu hören und weiterzumachen ...

Wie lehre ich innerhalb von 10 Stunden die Grundlagen für Computer -Anfänger für Programmierungen? Wenn Sie nur 10 Stunden Zeit haben, um Computer -Anfänger zu unterrichten, was Sie mit Programmierkenntnissen unterrichten möchten, was würden Sie dann beibringen ...

In dem Artikel werden beliebte Python-Bibliotheken wie Numpy, Pandas, Matplotlib, Scikit-Learn, TensorFlow, Django, Flask und Anfragen erörtert, die ihre Verwendung in wissenschaftlichen Computing, Datenanalyse, Visualisierung, maschinellem Lernen, Webentwicklung und h beschreiben

Fastapi ...

Wie kann man nicht erkannt werden, wenn Sie Fiddlereverywhere für Man-in-the-Middle-Lesungen verwenden, wenn Sie FiddLereverywhere verwenden ...
