Rapide et Précis Python Répétition de Minuterie
J'ai besoin d'envoyer de répéter les messages à partir d'une liste rapidement et précisément. Une liste des besoins pour envoyer les messages toutes les 100ms, avec un +/- 10ms fenêtre. J'ai essayé d'utiliser le code ci-dessous, mais le problème est que la minuterie attend les 100ms, et puis tout le calcul qui doit être fait, en faisant le minuteur de la chute de l'acceptable fenêtre.
La diminution de l'attente est un désordre, et peu fiables hack. Il y a un Verrou autour de la boucle de message dans le cas où la liste se trouve rejeté au cours de la boucle.
Pensées sur la façon d'obtenir python pour envoyer des messages de manière cohérente autour de 100ms? Grâce
from threading import Timer
from threading import Lock
class RepeatingTimer(object):
def __init__(self,interval, function, *args, **kwargs):
super(RepeatingTimer, self).__init__()
self.args = args
self.kwargs = kwargs
self.function = function
self.interval = interval
self.start()
def start(self):
self.callback()
def stop(self):
self.interval = False
def callback(self):
if self.interval:
self.function(*self.args, **self.kwargs)
Timer(self.interval, self.callback, ).start()
def loop(messageList):
listLock.acquire()
for m in messageList:
writeFunction(m)
listLock.release()
MESSAGE_LIST = [] #Imagine this is populated with the messages
listLock = Lock()
rt = RepeatingTimer(0.1,loop,MESSAGE_LIST)
#Do other stuff after this
Je comprends que les writeFunction va causer un peu de retard, mais pas plus que les 10ms permis. J'ai essentiellement besoin d'appeler la fonction à chaque 100ms pour chaque message. Le messagelist est de petite taille, généralement de moins d'éléments.
Le prochain défi est de faire ce travail avec tous les 10 ms, +/-1 ms 😛
OriginalL'auteur dwpriest | 2013-03-23
Vous devez vous connecter pour publier un commentaire.
Oui, la simple attente est en désordre et il existe de meilleures alternatives.
Tout d'abord, vous avez besoin d'un timer haute précision en Python. Il y a quelques solutions de rechange et en fonction de votre OS, vous pouvez choisir le plus précis.
Deuxièmement, vous devez être conscient de la notions de base multitâche préemptif et de comprendre qu'il n'est pas de haute précision
sleep
fonction, et que sa résolution réelle diffère d'un système à un trop. Par exemple, si nous parlons de Windows, le minimum de sommeil, l'intervalle peut être autour de 10 à 13 ms.Et la troisième, rappelez-vous qu'il est toujours possible d'attendre d'une très exacte de l'intervalle de temps (en supposant que vous avez un timer haute résolution), mais avec un compromis de charge élevée de l'UC. La technique est appelée occupé attente:
Donc, la solution est de créer un hybride de la minuterie. Il sera l'utilisation de l'
sleep
fonction d'attendre la majeure partie de l'intervalle, et puis il va commencer à sonder le timer haute précision dans la boucle, tout en faisant de lasleep(0)
truc.Sleep(0)
sera (selon la plate-forme) attendre le moins possible de temps, libérant le reste de la tranche de temps à d'autres processus de commutation et le contexte de PROCESSEUR. En voici un discussion.L'idée est bien décrites dans la Ryan Geiss est Timing Win32 article. C'est dans C, et de l'API Windows, mais les principes de base s'appliquent également ici.
Ne pas se laisser berner par la fantaisie "occupée" d'attente " de l'étiquette ;-). C'est une très mauvaise pratique et doit être évitée autant que possible.
OriginalL'auteur Vladimir Sinenko
Stocker l'heure de début. Envoyer le message. Obtenir la fin des temps. Calculer timeTaken=fin-début. Convertir FP secondes. Sleep(0.1-timeTaken). De retour de boucle.
OriginalL'auteur Martin James
essayez ceci:
OriginalL'auteur Percy Zahl