2012-08-25 15 views
4

我想每個分鐘執行一次循環,當datetime.utcnow().second爲零時。 到目前爲止,我有這個如何與UTC定時器進行循環同步並在每一分鐘執行一次?

while True: 
    while datetime.utcnow().second != 0: pass 
    do_something() 

但這個問題是我在浪費CPU進程。我會使用time.sleep(60),但我不知道它如何與UTC時鐘同步,因爲time.sleep(60)隨着時間的流逝可能會離開官方的UTC時間。

回答

11

我能想到的最好的辦法就是睡覺,直到下一分鐘:

while True: 
    sleeptime = 60 - datetime.utcnow().second 
    time.sleep(sleeptime) 
    ... 

如果你想成爲真正精確:

while True: 
    t = datetime.utcnow() 
    sleeptime = 60 - (t.second + t.microsecond/1000000.0) 
    time.sleep(sleeptime) 
    ... 

這休眠的必要時間如數以次秒的精度達到下一分鐘。

EDITED修復分鐘翻轉錯誤。

+1

請注意,time.sleep()不保證具有毫秒精度;它取決於底層OS睡眠功能的準確性。典型精度爲〜10ms(對於Windows)或〜1ms(對於Linux)。 –

+0

你是對的;在某些平臺上它不是1ms。我編輯了匹配的答案。 – nneonneo

+0

感謝這個片段,大概是我打算做的事情,但想要快速完整的檢查。 – Zeb

0

簡易方法也會被改變passsleep (1)這將大大緩解CPU的壓力,但在運行缺少零秒,如果由於某種原因,你得到12:30:59.99999其次12:31:01.00001的風險。

你可以選擇一個兩階段的方式。雖然有三秒鐘以上的時間,但請根據時間長短等待更長的時間。否則,等待一秒鐘。

類似如下的功能齊全的Python程序將說明我的意思:

from datetime import datetime 
from time import sleep 

def WaitForNextMinute(): 
    secs = datetime.utcnow().second 
    while secs < 57: 
     sleep (57 - secs) 
     secs = datetime.utcnow().second 
    while datetime.utcnow().second >= 57: 
     sleep (1) 

while True: 
    WaitForNextMinute() 
    print datetime.utcnow() 

輸出我的系統是:

2012-08-25 04:16:00.111257 
2012-08-25 04:17:00.157155 
2012-08-25 04:18:00.217356 
2012-08-25 04:19:00.270348 
2012-08-25 04:20:00.330203 
2012-08-25 04:21:00.390318 
2012-08-25 04:22:00.450440 
2012-08-25 04:23:00.510491 
2012-08-25 04:24:00.570487 
2012-08-25 04:25:00.630502 
2012-08-25 04:26:00.690523 
2012-08-25 04:27:00.750642 
2012-08-25 04:28:00.810780 
2012-08-25 04:29:00.870900 
2012-08-25 04:30:00.931078 

這是一個很值得你追求的。

此功能將基本上做一個等待,讓你非常接近分鐘結束,然後醒來每一秒,直到週期結束。

因此,例如,讓我們說這是12:21:13。由於secs低於57,它會等待57 - 13或足以讓你達到約12:21:57

從那裏,它將一次只睡一秒,直到second變得小於57。換句話說,當我們進入下一分鐘時。

通過做這種方式,而不是試圖檢測零秒,也繞過失蹤一分鐘的可能性。

而且,如果您想確保儘可能接近分鐘翻轉,可以用pass代替sleep (1)。這樣,你可以在60分鐘內完成最多三秒鐘的完全CPU咕嚕聲(平均5%),並儘可能接近分鐘翻轉。

當我執行稍加修改,我得到:

2012-08-25 05:48:00.000003 
2012-08-25 05:49:00.000003 
2012-08-25 05:50:00.000003 
2012-08-25 05:51:00.000004 
2012-08-25 05:52:00.000004 
2012-08-25 05:53:00.000004 
2012-08-25 05:54:00.000003 
2012-08-25 05:55:00.000004 
1

有趣的問題蟒蛇確實有辦法安排使用sched事件,並使其再次發生,你可以只是一次又一次地等調度。 ..

這裏是怎麼樣的。

>>> import sched, time, datetime 
>>> sch = sched.scheduler(time.time, time.sleep) 
>>> 
>>> count = 0 
>>> last = 0 
>>> def do_something(): 
...  global count, last 
...  if count != 5: 
...   sch.enter(5, 1, do_something,()) 
...  print datetime.datetime.now() - last 
...  last = datetime.datetime.now() 
...  count += 1 
... 
>>> sch.enter(5, 1, do_something,()) 
Event(time=1345872167.9454501, priority=1, action=<function do_something at 0x1004c4a28>, argument=()) 
>>> last = datetime.datetime.now() 
>>> sch.run() 

0:00:05.000015 
0:00:05.000159 
0:00:05.000184 
0:00:05.000183 
0:00:05.000181 
0:00:05.000148 
>>> 

有趣,它似乎是相當準確的,有輕微的開銷,可能是由於它需要執行的實際指令的時候,我想我們需要考慮到這些,如果我們想要完美的精確性..

相關問題