Python 2.x - Windows 毫秒级别的休眠调用
Python 2.x - sleep call at millisecond level on Windows
我在这个论坛上得到了一些关于如何在 Python 2 中编写时钟对象的非常好的提示。我现在可以使用一些代码了。这是一个 'ticks' 60 FPS 的时钟:
import sys
import time
class Clock(object):
def __init__(self):
self.init_os()
self.fps = 60.0
self._tick = 1.0 / self.fps
print "TICK", self._tick
self.check_min_sleep()
self.t = self.timestamp()
def init_os(self):
if sys.platform == "win32":
self.timestamp = time.clock
self.wait = time.sleep
def timeit(self, f, args):
t1 = self.timestamp()
f(*args)
t2 = self.timestamp()
return t2 - t1
def check_min_sleep(self):
"""checks the min sleep time on the system"""
runs = 1000
times = [self.timeit(self.wait, (0.001, )) for n in xrange(runs)]
average = sum(times) / runs
print "average min sleep time:", round(average, 6)
sort = sorted(times)
print "fastest, slowest", sort[0], sort[-1]
def tick(self):
next_tick = self.t + self._tick
t = self.timestamp()
while t < next_tick:
t = self.timestamp()
self.t = t
if __name__ == "__main__":
clock = Clock()
时钟还不错,但为了避免忙循环,我希望 Windows 比平时少睡 15 毫秒左右。在我的系统(64 位 Windows 10)上,如果 Python 是唯一 运行 的应用程序,它 returns 我在启动时钟时平均大约 15 / 16 毫秒.对于避免繁忙循环的分钟睡眠来说,这太长了。
有人知道我怎样才能让 Windows 的睡眠时间低于该值吗?
您可以暂时将计时器周期降低到 timeGetDevCaps
. The following defines a timer_resolution
context manager that calls the timeBeginPeriod
and timeEndPeriod
函数返回的 wPeriodMin
值。
import timeit
import contextlib
import ctypes
from ctypes import wintypes
winmm = ctypes.WinDLL('winmm')
class TIMECAPS(ctypes.Structure):
_fields_ = (('wPeriodMin', wintypes.UINT),
('wPeriodMax', wintypes.UINT))
def _check_time_err(err, func, args):
if err:
raise WindowsError('%s error %d' % (func.__name__, err))
return args
winmm.timeGetDevCaps.errcheck = _check_time_err
winmm.timeBeginPeriod.errcheck = _check_time_err
winmm.timeEndPeriod.errcheck = _check_time_err
@contextlib.contextmanager
def timer_resolution(msecs=0):
caps = TIMECAPS()
winmm.timeGetDevCaps(ctypes.byref(caps), ctypes.sizeof(caps))
msecs = min(max(msecs, caps.wPeriodMin), caps.wPeriodMax)
winmm.timeBeginPeriod(msecs)
yield
winmm.timeEndPeriod(msecs)
def min_sleep():
setup = 'import time'
stmt = 'time.sleep(0.001)'
return timeit.timeit(stmt, setup, number=1000)
例子
>>> min_sleep()
15.6137827
>>> with timer_resolution(msecs=1): min_sleep()
...
1.2827173000000016
在 with
块后恢复原始计时器分辨率:
>>> min_sleep()
15.6229814
我在这个论坛上得到了一些关于如何在 Python 2 中编写时钟对象的非常好的提示。我现在可以使用一些代码了。这是一个 'ticks' 60 FPS 的时钟:
import sys
import time
class Clock(object):
def __init__(self):
self.init_os()
self.fps = 60.0
self._tick = 1.0 / self.fps
print "TICK", self._tick
self.check_min_sleep()
self.t = self.timestamp()
def init_os(self):
if sys.platform == "win32":
self.timestamp = time.clock
self.wait = time.sleep
def timeit(self, f, args):
t1 = self.timestamp()
f(*args)
t2 = self.timestamp()
return t2 - t1
def check_min_sleep(self):
"""checks the min sleep time on the system"""
runs = 1000
times = [self.timeit(self.wait, (0.001, )) for n in xrange(runs)]
average = sum(times) / runs
print "average min sleep time:", round(average, 6)
sort = sorted(times)
print "fastest, slowest", sort[0], sort[-1]
def tick(self):
next_tick = self.t + self._tick
t = self.timestamp()
while t < next_tick:
t = self.timestamp()
self.t = t
if __name__ == "__main__":
clock = Clock()
时钟还不错,但为了避免忙循环,我希望 Windows 比平时少睡 15 毫秒左右。在我的系统(64 位 Windows 10)上,如果 Python 是唯一 运行 的应用程序,它 returns 我在启动时钟时平均大约 15 / 16 毫秒.对于避免繁忙循环的分钟睡眠来说,这太长了。
有人知道我怎样才能让 Windows 的睡眠时间低于该值吗?
您可以暂时将计时器周期降低到 timeGetDevCaps
. The following defines a timer_resolution
context manager that calls the timeBeginPeriod
and timeEndPeriod
函数返回的 wPeriodMin
值。
import timeit
import contextlib
import ctypes
from ctypes import wintypes
winmm = ctypes.WinDLL('winmm')
class TIMECAPS(ctypes.Structure):
_fields_ = (('wPeriodMin', wintypes.UINT),
('wPeriodMax', wintypes.UINT))
def _check_time_err(err, func, args):
if err:
raise WindowsError('%s error %d' % (func.__name__, err))
return args
winmm.timeGetDevCaps.errcheck = _check_time_err
winmm.timeBeginPeriod.errcheck = _check_time_err
winmm.timeEndPeriod.errcheck = _check_time_err
@contextlib.contextmanager
def timer_resolution(msecs=0):
caps = TIMECAPS()
winmm.timeGetDevCaps(ctypes.byref(caps), ctypes.sizeof(caps))
msecs = min(max(msecs, caps.wPeriodMin), caps.wPeriodMax)
winmm.timeBeginPeriod(msecs)
yield
winmm.timeEndPeriod(msecs)
def min_sleep():
setup = 'import time'
stmt = 'time.sleep(0.001)'
return timeit.timeit(stmt, setup, number=1000)
例子
>>> min_sleep()
15.6137827
>>> with timer_resolution(msecs=1): min_sleep()
...
1.2827173000000016
在 with
块后恢复原始计时器分辨率:
>>> min_sleep()
15.6229814