2012-07-25 66 views
4

我需要等待约25ms在我的一个功能。有时候这个函数在处理器被其他东西占用的时候被调用,而在其他时候被称为处理器的时候被调用。睡眠准确的时间在python

我试过time.sleep(.25),但有时它的实际25ms和其他时间需要更长的时间。无论处理器是否可用,是否有一种方法能够在一定的时间内进入睡眠状态?

+1

不,不是在非实时系统 – 2012-07-25 20:07:47

+0

是否使用Linux呢? – tMC 2012-07-25 20:12:06

+0

我正在使用Windows。 – Kreuzade 2012-07-25 20:14:17

回答

8

由于您使用的是操作系统preemptive,所以您无法保证您的进程能够在25ms内控制CPU。

如果你仍然想尝试,最好有一个忙轮循环,直到25ms过去。像这样的东西可能会工作:

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

为什么在这里忙着等着呢?这不取决于分配给每个进程的时间片的长度吗?如果标准时间片为25毫秒,则繁忙的等待肯定会更糟糕,因为它几乎*保证*在等待之后处理器将不可用,如果存在比核更多的活动进程。 – 2012-07-25 20:11:30

+1

根据我的理解,如果你的time.sleep为25ms,那么线程将从主动队列中取出,直到25ms过去,之后它将被移动到活动队列,然后在未来的某个时间点执行。如果您忙于等待,您将停留在活动队列中。 – 2012-07-25 20:30:59

6

0.25秒是250毫秒,而不是25.除此之外,在普通操作系统上无法等待正好 25毫秒 - 您需要一些实时操作系统。

2

你打算做的是一个实时应用程序。 Python(并且可能是您正在使用的操作系统)并不打算对时间限制非常严格的这类应用程序进行编程。

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

1

从睡眠方法的docs

挂起的秒的给定数量的执行。参数可能是 一个浮点数,表示更精确的睡眠时间。实际挂起时间可能比请求的要少,因为任何 捕获的信号将在执行该信号的捕获程序后终止睡眠()。此外,由于系统中的其他活动的调度,中止时间可能比任意量请求更长的 比

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

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) 

此代码将几乎机制保障您的过程会睡得0.25秒。注意虽然 - 你可能想要降低优先级为2或3,除非它是绝对至关重要的这个睡眠时间为0.25秒。当然,不要将用户最终产品的优先级过高。

0

在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)