Python如何在特定时间间隔内定期运行任务?

3
我有一个需求,需要每5秒运行一次任务,但只在特定时间段内运行(例如明天1:30到2:30之间)。
我看了下celery,但是普通任务不能在celery中重复执行,而周期性任务无法动态调度。
我还看了APScheduler,但它不支持将其作为“守护进程”运行并从外部调度任务。
有什么想法可以实现这个需求吗?
编辑:早些时候应该提到,我需要在Web请求期间执行此操作,就像后台任务一样。

通常情况下,这是通过在您的系统上使用类似于“crontab”的等效工具来完成的(Windows曾经有一个“at”命令,不知道最近版本是否还存在)。 - Paulo Scardine
2个回答

2
如果我正确理解了你的问题,是这个意思吗?
from time import sleep
from datetime import datetime


if 90 <= datetime.now().hour * 60 + datetime.now().minute <= 150:
    # Do something
    time.sleep(5)

我将小时转换为分钟,以便更轻松地处理时间。因此,90分钟是1.30,150分钟是2.30。(考虑上午)
并且时间模块使其以5秒的间隔运行。
如果您还需要天数,则可以轻松实现如下;
datetime.now().day

您需要将此放入循环中以持续测试条件。我使用的sleep方法会导致每5秒检查一次。

由于您添加的代码不能阻塞进程,另一种方法是使用分割方法。类似于:

While #condition:
    if not datetime.now().second % 5:
        # Process

当然,我必须补充说明,这是一个不好的解决方案,因为它总是在运行。所以,我相信使用一个合适的库会更有帮助,但目前我并不知道有哪些库可供使用。


如果你需要精度,那么 sleep 函数并不是一个好的选择。它只会将进程放入调度程序的锁定队列和就绪队列中,而不会确切地在 5 秒后继续进程。为了实现这一点,你应该使用 时钟信号 - Mr. E
你说得没错。我只是在想一个避免这个问题的方法。 :) 但在这个例子中,我认为它按预期工作,因为分钟可以被5整除。 - Rockybilly
谢谢。但是我需要在Web请求期间安排任务,它不应该阻塞。如果我将此脚本作为守护程序运行,并让其从Web代码触发特定间隔的函数。 - Scaraffe

1
我觉得如果你想要完全针对Python的答案,@Rockybilly的回答已经很接近了。然而,你需要将其包装在一个:

标签中。

While True:
#@Rockybilly's if statement

这是为了重复该过程所必需的。您还希望像这里看到的那样加入一些内容:延迟任务直到特定时间
您会在指定范围之外执行一次此操作(例如2:31),然后将脚本休眠,直到第二天的1:30。这有助于确保它不会不断运行。
正如人们评论的那样,您可以在某种程度上使用CRON(Unix)或Task Scheduler(Windows)来实现这一点。

--

既然你修改了问题,我会在这里添加对此编辑的回应。请查看下面针对@Rockybilly的评论,因为这是你可能想要澄清的内容。

如果需要并行运行,请考虑使用线程, 多进程或新的asyncio模块。

(由于声望限制,无法链接Asyncio)


谢谢您指出,我实际上几分钟前就添加了它 :) - Rockybilly
@Rockybilly 我看到了!太好了!我不能在上面评论(声望不够),但我认为E先生在你的评论中所说的是该函数将休眠5秒钟+运行脚本所需的时间。因此,如果脚本需要20秒才能运行,它将导致25秒的间隔。我认为这是OP需要澄清的问题。OP是否需要每 ~5秒钟得到结果?进程是否需要每5秒钟运行(由于负载原因,结果时间可能会有所不同)?或者,要求只是处理之间的5秒间隔? - disflux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接