【问题标题】:Call function every x seconds (Python) [duplicate]每 x 秒调用一次函数(Python)[重复]
【发布时间】:2017-10-28 14:59:18
【问题描述】:

我想每 10 秒调用一次函数(实际上是一个 Web API)。但是该函数可能需要随机 t 秒才能返回。 (假设 t 为 0.1 到 1.0 秒)

我们能想到的最简单的代码是

while True:
    func()          # take t sec
    time.sleep(10)  # sleep 10 sec

但在这种情况下,func 每 (1+t) 秒调用一次。 有更好的方法吗?

我们应该使用一些多线程或类似的东西吗?具体的代码示例将不胜感激。谢谢。

【问题讨论】:

  • stackoverflow.com/questions/1239035/… 可能相关?您可以每 10 秒为异步调用生成一个子进程。那么处理需要多长时间并不重要。
  • 你为什么不用cron
  • 你可以使用python内置标准库中的sched(scheduler)模块。
  • @YamanJain 你能说明如何安排吗?

标签: python api loops time


【解决方案1】:

只要记住下一次迭代应该发生的时间,大致是这样的(不是完全工作的代码,我相信你可以从这里弄清楚):

import time
nexttime = time.time()
while True:
    func()          # take t sec
    nexttime += 10
    sleeptime = nexttime - time.time()
    if sleeptime > 0:
        time.sleep(sleeptime)

【讨论】:

  • 谢谢。我认为这是最简单也是最好的方法。
【解决方案2】:

试试这个:

from multiprocessing import Pool
import time

pool = Pool(processes=1)              # Start a worker processes.
while true:
    result = pool.apply_async(func, [10], callback=finish) # Evaluate "func(10)" asynchronously calling callback when finished.
    time.sleep(10)

这将恰好每 10 秒调用一次您的函数。只要您确定返回时间不会超过 10 秒,您应该可以只使用一个工作进程。来源:Asynchronous method call in Python?

【讨论】:

  • 感谢您提供的漂亮代码。这是我模糊的想象。由于pool.apply_async调用时间,我发现间隔略长于10秒。
【解决方案3】:

我发现了另一种使用sched 模块的方法。

import time
import sched

def daemon(local_handler, t):
    print('time {}'.format(t))
    # call func here
    # time.sleep(2)
    local_handler.enterabs(t + 10, 1, daemon, (local_handler, t+10))

handler = sched.scheduler(time.time, time.sleep)
t = time.time()
handler.enter(0, 1, daemon, (handler, t))
handler.run()

这种方法的一个优点是我们可以精确地控制函数的时间。比如我们可以在时钟为0.31, 10.31, 20.31, 30.31, ...时调用该函数

此代码取自Python Scheduler vs loop + sleep

【讨论】:

    【解决方案4】:

    你可以这样使用:

    import time
    start=time.perf_counter()
    call_new_func()
    while ((time.perf_counter()-start)<desired_time_wait):
        pass #busy-wait
    

    在您的 while True 循环中。

    【讨论】:

    • 当然,如果您想浪费电力并降低计算机速度!注意 OP 的代码占空比小于 10%,所以这会浪费 90% 以上的资源。
    • 根据我对hg.python.org/cpython/file/tip/Modules/timemodule.c的理解,这种循环(C语言)其实是Python内部对time.sleep()做的。
    • 不,Python 使用select() 或其他非忙等待方法。正如您在链接的pysleep 的代码中看到的那样。
    猜你喜欢
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多