要考虑的那种应用是示波器或高速数据记录器。我有一个功能可以检索所需的信息,我只需要一次又一次地研究它,非常快速,高精度。
time.sleep()有一些限制,我认为不是这样的。
我已经研究了内置事件调度程序,但我认为它不够精确,并不能完全满足我的需求。
对此的要求是:
是否有任何现有的库满足这些要求?我不想重新发明轮子,但如果必须,我可能会使用Windows多媒体计时器(winmm.dll)。对此提出任何意见/建议吗?
答案 0 :(得分:3)
我知道我在回答自己的问题时已经迟到了,但希望它会对某人有所帮助。
我为Windows多媒体计时器编写了一个纯粹作为测试的包装器。它似乎工作得很好,但代码没有经过全面测试,也没有得到优化。
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()
,所以请用一点盐。
在使用10ms周期性定时器的长时间测试期间,我的旧双码3GHz机器的CPU使用率约为3%或更低。虽然机器闲置时似乎还在使用它,所以我说额外的CPU使用量是最小的。
答案 1 :(得分:2)
编辑:在编写下面的内容之后,我倾向于为python事件调度程序实现类似的测试。我不明白为什么你认为它不够准确。
像Linux这样的东西似乎在我的Linux下工作得很好(我没有理由认为它不适用于Windows)。每隔10ms,调用on_timer_event()
,根据实时时钟打印出自上次呼叫以来的时间。这显示了计时器的近似精度。最后,打印出总时间以显示没有漂移。
下面的代码似乎存在一个问题,偶尔会出现虚假(短间隔)的事件。我不知道为什么会这样,但毫无疑问,通过一些游戏,你可以让它变得可靠。我认为这种方法是可行的方法。
import pygame
import time
pygame.init()
TIMER_EVENT = pygame.USEREVENT+1
pygame.time.set_timer(TIMER_EVENT, 10)
timer_count = 0
MAX_TIMER_COUNT = 1000
def on_timer_event():
global last_time
global timer_count
new_time = time.time()
print new_time - last_time
last_time = new_time
timer_count += 1
if timer_count > MAX_TIMER_COUNT:
print last_time - initial_time
pygame.event.post(pygame.event.Event(pygame.QUIT, {}))
initial_time = time.time()
last_time = initial_time
while True:
event = pygame.event.wait()
if event.type == TIMER_EVENT:
on_timer_event()
elif event.type == pygame.QUIT:
break