2012-07-25 67 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)