Ответ 1
Я знаю, что опаздываю на игру, отвечая на мой собственный вопрос, но, надеюсь, это поможет кому-то.
Я написал обертку для Windows Multimedia Timer только как тест. Кажется, что он работает хорошо, но код не полностью протестирован и не оптимизирован.
mmtimer.py:
from ctypes import *
from ctypes.wintypes import UINT
from ctypes.wintypes import DWORD
timeproc = WINFUNCTYPE(None, c_uint, c_uint, DWORD, DWORD, DWORD)
timeSetEvent = windll.winmm.timeSetEvent
timeKillEvent = windll.winmm.timeKillEvent
class mmtimer:
def Tick(self):
self.tickFunc()
if not self.periodic:
self.stop()
def CallBack(self, uID, uMsg, dwUser, dw1, dw2):
if self.running:
self.Tick()
def __init__(self, interval, tickFunc, stopFunc=None, resolution=0, periodic=True):
self.interval = UINT(interval)
self.resolution = UINT(resolution)
self.tickFunc = tickFunc
self.stopFunc = stopFunc
self.periodic = periodic
self.id = None
self.running = False
self.calbckfn = timeproc(self.CallBack)
def start(self, instant=False):
if not self.running:
self.running = True
if instant:
self.Tick()
self.id = timeSetEvent(self.interval, self.resolution,
self.calbckfn, c_ulong(0),
c_uint(self.periodic))
def stop(self):
if self.running:
timeKillEvent(self.id)
self.running = False
if self.stopFunc:
self.stopFunc()
Периодический тестовый код:
from mmtimer import mmtimer
import time
def tick():
print("{0:.2f}".format(time.clock() * 1000))
t1 = mmtimer(10, tick)
time.clock()
t1.start(True)
time.sleep(0.1)
t1.stop()
Выход в миллисекундах:
0.00
10.40
20.15
29.91
39.68
50.43
60.19
69.96
79.72
90.46
100.23
Одноразовый тестовый код:
from mmtimer import mmtimer
import time
def tick():
print("{0:.2f}".format(time.clock() * 1000))
t1 = mmtimer(150, tick, periodic=False)
time.clock()
t1.start()
Выход в миллисекундах:
150.17
Как вы можете видеть из результатов, это довольно точно. Тем не менее, это использование только time.clock()
, поэтому возьмите их с щепоткой соли.
Во время длительного теста с периодическим таймером 10 мс, загрузка процессора составляет около 3% или меньше на моем старом двухцифровом 3GHz-устройстве. Машина также, похоже, использует это, когда он простаивает, поэтому я бы сказал, что использование дополнительного процессора минимально.