这篇文章参考了我之前的文章:
在上一篇文章中,我解释了我有一个名为Item的类对象。。这个Item类有一个方法,叫做make_request它在服务器上发出GET请求。现在,我已经实现了调用make_request的X Item对象.Item对象每隔X分钟调用一次该方法,但是这些make_requests必须独立调用。3项示例:
- 14:00 - Item0.make_request
- 14:01 - Item1.make_request
- 14:02 - Item2.make_request
- 14:03 - Item0.make_request
- 14:04 - Item1.make_request
- 14:05 - Item2.make_request
- 14:06 - Item0.make_request
- 14:07 - Item1.make_request
- 14:08 - Item2.make_request
- 14:09 - Item0.make_request
- 14:10 - Item1.make_request
- 14:11 - Item2.make_request
- 14:12 - Item0.make_request
- 14:13 - Item1.make_request
- 14:14 - Item2。make_request……等
原理很简单,对象Item_X的make_request方法必须独立于对象Item_X-1的前一个make_request方法被调用。实际上,make_request方法必须在M分钟(每分钟)启动,例如30秒。如果获得方法的结果需要超过30秒,那么它不能延迟下一个make_request (Multiprocess and queue?)
我上一篇文章的答案是有效的,但不够强大:)
我需要的是可能的解决方案。我想知道你是否有在python3中这样做的想法。你能给我一些建议(模块)吗?
您可以使用apscheduler来实现这一点。根据具体的用例,您可以进行许多设置来实现这一点。例如,将每个项拆分为它自己的作业:
import time
from datetime import datetime, timedelta
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.interval import IntervalTrigger
class Item:
def __init__(self, name):
self.name = name
def make_request(self):
print(f"{datetime.now()}: {self.name}")
items = [
Item(name="Item0"),
Item(name="Item1"),
Item(name="Item2"),
]
scheduler = BlockingScheduler() # blocks the main thread
for i, item in enumerate(items):
scheduler.add_job(item.make_request,
IntervalTrigger(minutes=len(items)), # every item is executed once per minute
next_run_time=datetime.now() + timedelta(minutes=i), # delay items execution by a minute
)
scheduler.start()
样本输出:
2021-01-19 23:27:27.926250: Item0
2021-01-19 23:28:27.928920: Item1
2021-01-19 23:29:27.924316: Item2
2021-01-19 23:30:27.927307: Item0
2021-01-19 23:31:27.927305: Item1
2021-01-19 23:32:27.931385: Item2
如果make_request
完成所需的时间比项目多,则可以在任务完成后重新触发该任务,或者允许并发执行同一任务。另一种可能性是使用CRON触发器来调度作业,而不是使用next_run_time
延迟。
如果你绝对想要项目同步,那么你可以有一个单一的作业运行与max_instances=len(items)
, &维护标志以查看当前正在运行的项目。然而,这可能容易产生竞争条件& &;一般来说,需要更多的机械代码。