我正在尝试Task
使用Python 3的相对较新的asyncio
模块正确理解和实现两个同时运行的对象。
简而言之,asyncio似乎旨在处理Task
事件循环中的异步过程和并发执行。它促进了await
(应用于异步函数中)作为无回调方式等待和使用结果的使用,而不会阻塞事件循环。(期货和回调仍然是可行的选择。)
它还提供了asyncio.Task()
该类,该类是Future
设计用于包装协程的专门子类。最好通过使用该asyncio.ensure_future()
方法来调用。异步任务的预期用途是允许独立运行的任务与同一事件循环中的其他任务“同时”运行。我的理解是Tasks
连接到事件循环,然后该循环自动继续驱动await
语句之间的协程。
我喜欢无需使用任何一个Executor
类就可以使用并发Task的想法,但是在实现方面我没有发现太多细节。
这是我目前正在做的事情:
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
。