Python线程以精确的时间间隔执行

标签 python multithreading datetime signals alarm

我想创建一个以指定时间间隔执行的函数,比如说每 30 秒执行一次,时间如下:12:37:00.000000, 12:37 :30.000000, 12:38:00.000000

现在,最简单的方法是创建一个线程,运行一个函数,该函数有一个 while 循环,最后有一个 sleep(30) ,因此在最后等待 30 秒。我的应用程序将全天候(24/7)运行,假设从开始后 2-3 小时,执行该函数的实际时间将是 X:X:00.5X:X:33.5(因为 sleep(30) 上面有很多代码),因此每 30 秒就会稍微延迟我的工作,并且在很少的时间内小时,相差相当大。

我正在寻找一种优雅的方法来设置闹钟,每 30 秒触发一次,但总是恰好 30 秒,不多也不少,因为精度是必须的。

最佳答案

您可以推出自己的方法:

from datetime import datetime, timedelta
import time

def every_30s():
    print("fired at", datetime.now())

    
now = datetime.now()

# Align to the next 30 second event from the current time
if now.second >= 30:
    next_fire = now.replace(second=30, microsecond=0) + timedelta(seconds=30)
else:
    next_fire = now.replace(second=0, microsecond=0) + timedelta(seconds=30)
    
sleep = (next_fire - now).seconds - 2

while True:
    # Sleep for most of the time
    time.sleep(sleep)
    
    # Wait until the precise time is reached
    while datetime.now() < next_fire:
        pass
        
    every_30s()
    next_fire += timedelta(seconds=30)   # Advance 30 seconds
    sleep = 28

这首先与下一个 30 秒间隔对齐并触发事件。然后它会休眠 28 秒(以减少负载),然后快速检查下一次触发时间是否已过。下一次点火时间将提前 30 秒。

这将确保时间永远不会漂移。如果机器负载过重,它可能会稍晚触发,但下一个事件会再次准时。

示例输出:

fired at 2017-11-27 11:41:00
fired at 2017-11-27 11:41:30
fired at 2017-11-27 11:42:00
fired at 2017-11-27 11:42:30
fired at 2017-11-27 11:43:00
fired at 2017-11-27 11:43:30
fired at 2017-11-27 11:44:00

关于Python线程以精确的时间间隔执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47509168/

相关文章:

Python3 使用 Smtplib 发送电子邮件 [Yandex]

c# - 异步方法引发异常

c# - ManualResetEventSlim 建议的等待时间

java - 使 Spring bean 的行为类似于 ExecutorService 的 ThreadLocal 实例

javascript - Angularjs 日期时间选择器时区

javascript - Python 到 JavaScript unix 时间转换

python - 如何在 lambda 函数中执行赋值

python - 使用 XPath 在使用 python 的 <td> 单元格中获取文本

python - 在 GeoDjango 中获取距离最近的几何图形的最快方法

java - 如何获得当天到目前为止的总分钟数?