我需要在我的一个功能中等待大约25ms。有时,当处理器被其他东西占用时,会调用此函数,有时则会将处理器全部用于自身。
我已尝试time.sleep(.25)
但有时它实际上是25毫秒,有时则需要更长时间。无论处理器可用性如何,有没有办法在一段时间内睡眠?
答案 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)
编辑这个废话似乎没必要。试试吧:
>>> 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))