Python 2.x - sleep call at millisecond level on Windows

后端 未结 1 813
青春惊慌失措
青春惊慌失措 2021-01-07 03:13

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:

1条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-07 03:53

    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
    

    The original timer resolution is restored after the with block:

    >>> min_sleep()
    15.6229814
    

    0 讨论(0)
提交回复
热议问题