如何与UTC计时器进行循环同步并在每分钟执行一次?

python timer sync clock

4022 观看

3回复

659 作者的声誉

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

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

但问题是我浪费了cpu进程。我会使用time.sleep(60),但我不知道它将如何与UTC时钟同步,因为time.sleep(60)可能会随着时间的推移偏离官方UTC时间。

作者: user299648 的来源 发布者: 2012 年 8 月 25 日

回应 (3)


11

131166 作者的声誉

决定

我能想到的最佳方式是睡到下一分钟:

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

这精确到达下一分钟所需的时间,精确到亚秒级。

编辑修复分钟翻转错误。

作者: nneonneo 发布者: 25.08.2012 03:59

0

657981 作者的声誉

天真的方法也会被更改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)用a 替换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
作者: paxdiablo 发布者: 25.08.2012 04:03

1

8008 作者的声誉

有趣的问题python确实有一种方法来使用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
>>>

有趣的是,它似乎非常准确,可能由于执行实际指令所需的时间略有开销,我想我们需要考虑它们,如果我们想要完美的准确性......

作者: Samy Vilar 发布者: 25.08.2012 04:54
32x32