我很难理解AsyncIOScheduler是如何工作的,它是如何非阻塞的?
如果我的工作是执行阻塞函数,AsyncIOScheduler
会阻塞吗?
如果我将AsyncIOScheduler
与ThreadPoolExecutor
结合使用呢?这是如何工作的呢?我能等任务执行吗?
发布于 2020-07-29 16:03:43
因此,在APScheduler中有三个重要的组件:
对于这个问题,只有1和2是相关的。
调度程序只是根据作业的间隔设置来决定何时调用作业,在AsyncIOScheduler
的情况下,它使用异步实现等待期的非阻塞。它运行在与主进程相同的进程和线程中。如果您的应用程序已经在异步循环上运行,这是非常有用的,因为它节省了运行新进程/线程的开销。
现在,当一个作业需要执行时,它是被调用的执行器,在AsyncIOScheduler
的情况下,默认是使用AsyncIOExecutor
,如果作业函数被签名为异步,它运行在与Scheduler相同的线程和进程中,否则它使用异步run_in_executor在线程池中运行它。
这就引出了最后一个问题,如果我们将AsyncIOScheduler
与ThreadPoolExecutor
结合使用会发生什么?从技术上讲,这与使用带有非异步函数的默认执行器相同,它将在线程池中运行,但调度程序将保留在主线程中。
发布于 2020-07-29 15:24:57
利用一些网络资源,我找到了一些有用的事实。希望它能帮到你。
一个典型的APScheduler实例包含数十个作业,它们执行常规的Python函数。APScheduler实例可以调度的作业数量没有限制;它只取决于机器的实际负载。默认情况下,APScheduler将所有作业存储在内存中.如果您希望您的作业能够从进程重新启动中存活下来,并且从上次触发时一直保持触发状态,则可以将这些作业存储在数据库中,例如任何关系数据库管理系统、Redis、MongoDB等。
根据应用程序的运行方式,它可以作为线程或异步任务运行,也可以作为异步任务运行。初始化时,APScheduler不会执行任何操作,除非您将Python函数添加为作业。一旦添加了所有作业,就需要“启动”调度程序。关于如何使用APScheduler的一个简单示例,这里有一个代码片段,它只起作用。
from urllib.request import urlopen
from apscheduler.schedulers.blocking import BlockingScheduler
scheduler = BlockingScheduler()
@scheduler.scheduled_job("interval", seconds=10)
def keep_warm():
urlopen("https://enqueuezero.com", timeout=10)
scheduler.start()
这确保每10秒请求一个URL。该程序作为阻塞进程运行。如果您想将它们与应用程序共存,可以考虑使用BackgroundScheduler
、AsyncIOScheduler
等。
这里有一些用于BackgroundScheduler
的代码片段。
from datetime import datetime
import time
import os
from apscheduler.schedulers.background import BackgroundScheduler
def tick():
print('Tick! The time is: %s' % datetime.now())
if __name__ == '__main__':
scheduler = BackgroundScheduler()
scheduler.add_job(tick, 'interval', seconds=3)
scheduler.start()
print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))
try:
# This is here to simulate application activity (which keeps the main thread alive).
while True:
time.sleep(2)
except (KeyboardInterrupt, SystemExit):
# Not strictly necessary if daemonic mode is enabled but should be done if possible
scheduler.shutdown()
下面的代码将演示如何使用asyncio
兼容的调度程序来调度以3秒钟间隔执行的作业。
import asyncio
import os
from datetime import datetime
from apscheduler.schedulers.asyncio import AsyncIOScheduler
def tick():
print('Tick! The time is: %s' % datetime.now())
if __name__ == '__main__':
scheduler = AsyncIOScheduler()
scheduler.add_job(tick, 'interval', seconds=3)
scheduler.start()
print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))
# Execution will block here until Ctrl+C (Ctrl+Break on Windows) is pressed.
try:
asyncio.get_event_loop().run_forever()
except (KeyboardInterrupt, SystemExit):
pass
您可以使用此链接获得有关ap调度程序的更多示例!
发布于 2020-07-27 17:12:51
基于文档,在事件循环中执行AsyncIOScheduler。
它是非阻塞的,因为它只需将自己添加到事件循环中,并等待您启动它。
一旦事件循环启动,它将异步运行。
from apscheduler.schedulers.asyncio import AsyncIOScheduler
import asyncio
async def job():
print('hi')
scheduler = AsyncIOScheduler()
scheduler.add_job(job, "interval", seconds=3)
scheduler.start()
asyncio.get_event_loop().run_forever()
输出
Run time of job "job (trigger: interval[0:00:03], next run at: 2020-07-27 14:06:39 -03)" was missed by 0:00:02.542515
hi
hi
https://stackoverflow.com/questions/63001954
复制相似问题