我想有一个循环中每分钟一次执行时datetime.utcnow().second
是零。 到目前为止,我有这个
while True:
while datetime.utcnow().second != 0: pass
do_something()
但这样做的问题是,我在浪费CPU进程。 我会用time.sleep(60)
但我不知道它将如何与UTC时钟同步,因为time.sleep(60)
可以从官方UTC时间随着时间的推移流浪。
我想有一个循环中每分钟一次执行时datetime.utcnow().second
是零。 到目前为止,我有这个
while True:
while datetime.utcnow().second != 0: pass
do_something()
但这样做的问题是,我在浪费CPU进程。 我会用time.sleep(60)
但我不知道它将如何与UTC时钟同步,因为time.sleep(60)
可以从官方UTC时间随着时间的推移流浪。
我能想到的最好的办法就是睡觉,直到下一分钟:
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)
...
这休眠的要达到下一分钟的时候完全量,以亚秒级的精度。
编辑以修复分钟翻转错误。
有趣的问题蟒蛇确实有一种方式来安排活动使用排程 ,并使其再次发生,你可以只是一次又一次地等安排吧...
这里怎么会是什么样子。
>>> 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
>>>
有趣的,这似乎是相当准确的,有轻微的开销,可能是由于它需要执行的实际指令的时候,我想我们需要考虑到这些,如果我们想要完美的准确性?
天真的做法是太改变pass
到sleep (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
。 换句话说,当我们滚入下一分钟。
通过做这种方式,而不是试图检测零秒,也绕过失踪一分钟的可能性。
而且,如果你想确保你尽可能靠近分钟侧翻越好,你可以更换sleep (1)
具有pass
。 这样,你会在全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