【问题标题】:Schedule an iterative function every x seconds without drifting每 x 秒安排一次迭代函数,不会漂移
【发布时间】:2023-01-07 06:58:44
【问题描述】:

完整的新手在这里对我如此裸露。我有许多设备向单个位置报告状态更新,并且随着更多站点的添加,随 time.sleep(x) 的漂移变得越来越明显,并且随着现在连接的站点越来越多,它已经完全翻了一番迭代之间的休眠时间。

import time


...
def client_list():
    sites=pandas.read_csv('sites')
    return sites['Site']


def logs(site):
    time.sleep(x)
    if os.path.isfile(os.path.join(f'{site}/target/', 'hit')):
        stamp = time.strftime('%Y-%m-%d,%H:%M:%S')
        log = open(f"{site}/log", 'a')
        log.write(f",{stamp},{site},hit\n")
        log.close()
        os.remove(f"{site}/target/hit")
    else:
        stamp = time.strftime('%Y-%m-%d,%H:%M:%S')
        log = open(f"{site}/log", 'a')
        log.write(f",{stamp},{site},miss\n")
        log.close()
...


if __name__ == '__main__':
    while True:
        try:
            client_list()
            with concurrent.futures.ThreadPoolExecutor() as executor:
                executor.map(logs, client_list())
...

我确实尝试用这个添加漂移计算:

from datetime import datetime, timedelta


def logs(site):
    first_called=datetime.now()
    num_calls=1
    drift=timedelta()
    time_period=timedelta(seconds=5)
    while 1:
        time.sleep(n-drift.microseconds/1000000.0)
        current_time = datetime.now()
        num_calls += 1
        difference = current_time - first_called
        drift = difference - time_period* num_calls
        if os.path.isfile(os.path.join(f'{site}/target/', 'hit')):
...

它以日志中的重复条目结束,并且该过程仍然漂移。 有没有更好的方法来安排函数每 x 秒运行一次并考虑开始时间的漂移?

【问题讨论】:

  • time.sleep(n-drift.microseconds/1000000.0) --> 'n' 是什么?
  • 抱歉,这与上面的 time.sleep(x) 相同;所以5秒。
  • 所以 n = time_period in time.sleep(n-drift.microseconds/1000000.0) ??

标签: python python-3.x python-multithreading concurrent.futures sched


【解决方案1】:

在下一个时间间隔创建一个等于所需系统时间的变量。每次通过循环将该变量增加 5 秒。计算睡眠时间,以便睡眠将在所需时间结束。时间不会很完美,因为睡眠间隔不是非常精确,但错误不会累积。你的 logs 函数看起来像这样:

def logs(site):
    next_time = time.time() + 5.0
    while 1:
        time.sleep(time.time() - next_time)
        next_time += 5.0
        if os.path.isfile(os.path.join(f'{site}/target/', 'hit')):
            # do something that takes a while

【讨论】:

    【解决方案2】:

    所以我设法找到了另一条不会漂移的路线。另一种方法仍然随着时间的流逝而漂移。通过捕获当前时间并查看它是否可以被 x(下例中的 5)整除,我能够防止时间出现偏差。

    def timer(t1,t2)
        return True if t1 % t2 == 0 else False
    
    def logs(site):
      while 1:
        try:
          if timer(round(time.time(), 0), 5.0):
             if os.path.isfile(os.path.join(f'{site}/target/', 'hit')):
                # do something that takes a while
                time.sleep(1) ''' this kept it from running again immediately if the process was shorter than 1 second. '''
    ...
    

    【讨论】:

      猜你喜欢
      • 2019-06-06
      • 1970-01-01
      • 2015-04-28
      • 2021-12-18
      • 1970-01-01
      • 2021-11-13
      • 2018-12-19
      • 1970-01-01
      • 2011-09-04
      相关资源
      最近更新 更多