Python 2.x-Windows上毫秒级的睡眠调用 [英] Python 2.x - sleep call at millisecond level on Windows

查看:124
本文介绍了Python 2.x-Windows上毫秒级的睡眠调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个论坛上,我得到了一些很好的关于如何用Python 2编写时钟对象的提示。我现在有一些代码在工作。时钟在60 FPS时滴答:

I was given some very good hints in this forum about how to code a clock object in Python 2. I've got some code working now. It's a clock that 'ticks' at 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是唯一正在运行的应用程序,那么在启动时钟时,它平均会返回15/16毫秒。

The clock does not do too bad, but in order to avoid a busy loop I'd like Windows to sleep less than the usual about 15 milliseconds. On my system (64-bit Windows 10), it returns me an average of about 15 / 16 msecs when starting the clock if Python is the only application that's running. That's way too long for a min sleep to avoid a busy loop.

有人知道我怎样才能使Windows的睡眠时间少于这个值吗?

Does anybody know how I can get Windows to sleep less than that value?

推荐答案

您可以暂时将计时器期限降低到wPeriodMin 值https://msdn.microsoft.com/zh-cn/library/dd757627 rel = nofollow> timeGetDevCaps 。下面定义了一个 timer_resolution 上下文管理器,该上下文管理器调用 timeBeginPeriod timeEndPeriod 函数。

You can temporarily lower the timer period to the wPeriodMin value returned by timeGetDevCaps. The following defines a timer_resolution context manager that calls the timeBeginPeriod and timeEndPeriod functions.

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)



示例



Example

>>> min_sleep()
15.6137827

>>> with timer_resolution(msecs=1): min_sleep()
...
1.2827173000000016

with 块之后恢复原始计时器分辨率:

The original timer resolution is restored after the with block:

>>> min_sleep()
15.6229814

这篇关于Python 2.x-Windows上毫秒级的睡眠调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆