python的sched模块可以在任务执行期间不阻塞地运行异步任务吗?
Posted
技术标签:
【中文标题】python的sched模块可以在任务执行期间不阻塞地运行异步任务吗?【英文标题】:Can python's sched module run asynchronous tasks without blocking during a task execution? 【发布时间】:2019-11-18 21:35:27 【问题描述】:我有一个 Module 类,带有一个 invoke()
方法,它可能会执行一些 IO 绑定/等待。
我使用sched
以不同的时间间隔运行所述类的多个实例,这种方式可能会使长时间运行的调用与另一个任务重叠。
sched
模块能否生成不同的任务并以非阻塞方式处理它们,如果不能,哪个模块可以为多个重复的并发任务完成这项工作?
我查看了sched
,但找不到任何明确的答案。
我还查看了asyncio
,这提示我有两个似乎不符合我需求的答案,分别是while True
(which seems cumbersome) 和Tasks (which doesn't appear to allow to run multiple methods concurrently)。
【问题讨论】:
Asyncio 模块就是您所需要的。 根据我能找到的情况,我猜的差不多了,但是我应该遵循哪种结构来正确地制作经常性的并发计划任务? 【参考方案1】:研究下面的代码,Luciano Ramalho 的 Fluent Python 第 18 章是关于 asyncio 模块的优秀资源。另外,永远不要忘记https://docs.python.org/3/library/asyncio.html
上的文档本身#!/usr/bin/env python3
# spinner_asyncio.py
# credits: Example by Luciano Ramalho inspired by
# Michele Simionato's multiprocessing example in the python-list:
# https://mail.python.org/pipermail/python-list/2009-February/538048.html
import asyncio
import itertools
import sys
@asyncio.coroutine # <1>
def spin(msg):
write, flush = sys.stdout.write, sys.stdout.flush
for char in itertools.cycle('|/-\\'):
status = char + ' ' + msg
write(status)
flush()
write('\x08' * len(status))
try:
yield from asyncio.sleep(.1) # <3>
except asyncio.CancelledError: # <4>
break
write(' ' * len(status) + '\x08' * len(status))
@asyncio.coroutine
def slow_function(): # <5>
# pretend waiting a long time for I/O, Non-blocking call!
yield from asyncio.sleep(3) # <6>
return 42
@asyncio.coroutine
def supervisor(): # <7>
spinner = asyncio.async(spin('thinking!')) # <8>
print('spinner object:', spinner) # <9>
result = yield from slow_function() # <10>
spinner.cancel() # <11>
return result
def main():
loop = asyncio.get_event_loop() # <12>
result = loop.run_until_complete(supervisor()) # <13>
loop.close()
print('Answer:', result)
if __name__ == '__main__':
main()
1: 用于 asyncio 的协程应该用 @asyn 修饰 cio.coroutine。这不是强制性的,但强烈建议这样做。
3:使用 asyncio.sleep(.1) 中的 yield 而不是 time.sleep(.1) 来休眠 不阻塞事件循环。
4:如果在 spin 唤醒后引发 asyncio.CancelledError,那是因为 已请求取消,因此退出循环。
5:slow_function 是协程,使用yield from 让事件循环 在这个协程假装通过睡眠进行 I/O 时继续进行。
6: yield from asyncio.sleep(3) 表达式处理控制流到 主循环,它将在睡眠延迟后恢复这个协程。
7: supervisor也是一个协程,所以它可以通过yield驱动slow_function 来自。
8: asyncio.async(...) 调度自旋协程运行,将其包装在一个任务中 对象,立即返回
9:显示任务对象。输出看起来像 Task pending coro= spin() 在 spinner_asyncio.py:12 运行。
10: 驱动 slow_function()。完成后,获取返回值。 同时,事件循环将继续运行,因为 slow_function 最终使用来自 asyncio.sleep(3) 的 yield 将控制权交还给 main 循环。
11:可以取消一个Task对象;这会在产量处引发 asyncio.CancelledError 协程当前暂停的行。协程可能会捕获 异常和延迟甚至拒绝取消。
12:获取事件循环的引用。
13:驱动supervisor协程完成;协程的返回值 是这个调用的返回值。
【讨论】:
以上是关于python的sched模块可以在任务执行期间不阻塞地运行异步任务吗?的主要内容,如果未能解决你的问题,请参考以下文章