【发布时间】:2015-05-29 22:23:15
【问题描述】:
我正在尝试使用 Python 3 相对较新的 asyncio 模块正确理解和实现两个同时运行的 Task 对象。
简而言之,asyncio 似乎旨在通过事件循环处理异步进程和并发Task 执行。它提倡使用await(应用于异步函数)作为等待和使用结果的无回调方式,而不会阻塞事件循环。 (期货和回调仍然是一个可行的选择。)
它还提供了asyncio.Task() 类,这是Future 的专门子类,旨在包装协程。最好使用asyncio.ensure_future() 方法调用。 asyncio 任务的预期用途是允许独立运行的任务与同一事件循环中的其他任务“同时”运行。我的理解是Tasks 连接到事件循环,然后在await 语句之间自动继续驱动协程。
我喜欢能够使用并发任务而不需要使用Executor 类之一的想法,但我没有找到关于实现的详细说明。
这就是我目前的做法:
import asyncio
print('running async test')
async def say_boo():
i = 0
while True:
await asyncio.sleep(0)
print('...boo {0}'.format(i))
i += 1
async def say_baa():
i = 0
while True:
await asyncio.sleep(0)
print('...baa {0}'.format(i))
i += 1
# wrap in Task object
# -> automatically attaches to event loop and executes
boo = asyncio.ensure_future(say_boo())
baa = asyncio.ensure_future(say_baa())
loop = asyncio.get_event_loop()
loop.run_forever()
在尝试同时运行两个循环任务的情况下,我注意到除非任务具有内部await 表达式,否则它将卡在while 循环中,从而有效地阻止其他任务运行(很多就像普通的while 循环一样)。但是,一旦任务必须(a)等待,它们似乎可以同时运行而没有问题。
因此,await 语句似乎为事件循环提供了一个在任务之间来回切换的立足点,从而产生并发的效果。
带有内部await的示例输出:
running async test
...boo 0
...baa 0
...boo 1
...baa 1
...boo 2
...baa 2
示例输出没有内部await:
...boo 0
...boo 1
...boo 2
...boo 3
...boo 4
问题
此实现是否通过asyncio 中并发循环任务的“正确”示例?
唯一可行的方法是让Task 提供一个阻塞点(await 表达式)以便事件循环处理多个任务,这是否正确?
【问题讨论】:
-
是的,任务从
yield from自动执行到下一个yield from。
标签: python concurrency task python-3.4 python-asyncio