在python中睡觉准确的时间

时间:2012-07-25 20:04:08

标签: python windows sleep

我需要在我的一个功能中等待大约25ms。有时,当处理器被其他东西占用时,会调用此函数,有时则会将处理器全部用于自身。

我已尝试time.sleep(.25)但有时它实际上是25毫秒,有时则需要更长时间。无论处理器可用性如何,有没有办法在一段时间内睡眠?

7 个答案:

答案 0 :(得分:9)

因为你正在使用preemptive操作系统,所以你无法保证你的进程能够在25ms内控制CPU。

如果您还想尝试,最好有一个繁忙的循环,轮询直到25ms过去。这样的事情可能有用:

import time
target_time = time.clock() + 0.025
while time.clock() < target_time:
    pass

答案 1 :(得分:6)

0.25秒是250毫秒,而不是25.除此之外,没有办法在常见的操作系统上等待完全 25毫秒 - 你需要一些实时操作系统。

答案 2 :(得分:4)

你在哪个系统?如果你在Windows上,你可能想要做这样的事情以确切的时间:

import ctypes
kernel32 = ctypes.windll.kernel32

# This sets the priority of the process to realtime--the same priority as the mouse pointer.
kernel32.SetThreadPriority(kernel32.GetCurrentThread(), 31)
# This creates a timer. This only needs to be done once.
timer = kernel32.CreateWaitableTimerA(ctypes.c_void_p(), True, ctypes.c_void_p())
# The kernel measures in 100 nanosecond intervals, so we must multiply .25 by 10000
delay = ctypes.c_longlong(.25 * 10000)
kernel32.SetWaitableTimer(timer, ctypes.byref(delay), 0, ctypes.c_void_p(), ctypes.c_void_p(), False)
kernel32.WaitForSingleObject(timer, 0xffffffff)

这段代码几乎可以保证你的进程会睡眠.25秒。注意 - 你可能想要将优先级降低到2或3,除非绝对关键这个睡眠时间为.25秒。当然不要将用户端产品的优先级更改为太高。

答案 3 :(得分:2)

您打算做的是实时应用程序。 Python(可能是您正在使用的操作系统)并不打算对时间限制如此严格的应用程序进行编程。

为了实现您的目标,您需要一个RTOS(实时操作系统),并根据RT最佳实践使用合适的编程语言(通常为C)开发您的应用程序。

答案 4 :(得分:2)

Windows 10中的

编辑这个废话似乎没必要。试试吧:

>>> from time import sleep
>>> import timeit
>>> '%.2f%% overhead' % (timeit.timeit('sleep(0.025)', number=100, globals=globals()) / 0.025 - 100)
'0.29% overhead'

.29%或其左右,开销相当低,通常不够准确。

以前的Windows版本 默认情况下的睡眠分辨率为55毫秒,这意味着您的睡眠呼叫需要25到55毫秒之间。要将睡眠分辨率降至1毫秒,您需要通过调用timeBeginPeriod来设置Windows使用的分辨率:

import ctypes
winmm = ctypes.WinDLL('winmm')
winmm.timeBeginPeriod(1)

答案 5 :(得分:1)

来自睡眠方法的docs

  

暂停执行指定的秒数。争论可能是   浮点数表示更精确的睡眠时间。该   实际停工时间可能比所要求的更少,因为任何   捕获信号将在执行后终止sleep()   信号的捕捉程序。此外,暂停时间可能更长   由于调度而导致的任意数量   系统中的其他活动。

事实是,它取决于你的底层操作系统。

答案 6 :(得分:0)

准确计时和延迟的另一种解决方案是从模块时间使用perf_counter()函数。在windows中特别有用,因为time.sleep在几毫秒内不准确。请参见下面的示例,其中函数accurate_delay以毫秒为单位创建延迟。

import time


def accurate_delay(delay):
    ''' Function to provide accurate time delay in millisecond
    '''
    _ = time.perf_counter() + delay/1000
    while time.perf_counter() < _:
        pass


delay = 10
t_start = time.perf_counter()
print('Wait for {:.0f} ms. Start: {:.5f}'.format(delay, t_start))

accurate_delay(delay)

t_end = time.perf_counter()
print('End time: {:.5f}. Delay is {:.5f} ms'.
      format(t_end, 1000*(t_end - t_start)))

sum = 0
ntests = 1000
for _ in range(ntests):
    t_start = time.perf_counter()
    accurate_delay(delay)
    t_end = time.perf_counter()
    print('Test completed: {:.2f}%'.format(_/ntests * 100), end='\r', flush=True)
    sum = sum + 1000*(t_end - t_start) - delay

print('Average difference in time delay is {:.5f} ms.'.format(sum/ntests))