如何有循环同步与UTC计时器,并在每个新执行分钟?(How to have loop sync wi

2019-07-31 03:52发布

我想有一个循环中每分钟一次执行时datetime.utcnow().second是零。 到目前为止,我有这个

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

但这样做的问题是,我在浪费CPU进程。 我会用time.sleep(60)但我不知道它将如何与UTC时钟同步,因为time.sleep(60)可以从官方UTC时间随着时间的推移流浪。

Answer 1:

我能想到的最好的办法就是睡觉,直到下一分钟:

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

这休眠的要达到下一分钟的时候完全量,以亚秒级的精度。

编辑以修复分钟翻转错误。



Answer 2:

有趣的问题蟒蛇确实有一种方式来安排活动使用排程 ,并使其再次发生,你可以只是一次又一次地等安排吧...

这里怎么会是什么样子。

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

有趣的,这似乎是相当准确的,有轻微的开销,可能是由于它需要执行的实际指令的时候,我想我们需要考虑到这些,如果我们想要完美的准确性?



Answer 3:

天真的做法是太改变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 。 换句话说,当我们滚入下一分钟。

通过做这种方式,而不是试图检测零秒,也绕过失踪一分钟的可能性。

而且,如果你想确保你尽可能靠近分钟侧翻越好,你可以更换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


文章来源: How to have loop sync with UTC timer and execute at every new minute?