书接上文。
并行执行任务
任务是与事件循环交互的主要方式之一。任务包装协程并跟踪它们完成的时间。任务是 的子类,因此其它协程可以等待任务,并且每个任务都有一个结果,可以在任务完成后获取。
启动任务
使用 创建任务实例。只要事件循环正在运行且协程不返回,生成的任务将作为事件循环管理的并发操作的一部分运行:
函数在退出前等待任务返回结果:
取消任务
通过保留 返回的任务对象,可以在任务完成之前取消其操作:
在启动事件循环之前取消任务时, 会抛出 异常:
如果某个任务在等待另一个并发操作时被取消,则会通过在其等待的位置抛出 异常来通知该任务:
捕获该异常可以清理已完成工作:
从协程创建任务
返回一个与协程的执行相关联的任务。然后,可以将该任务实例传递给其他代码,这些代码可以在不知道原始的协程是如何构造或调用的情况下等待它:
可以注意到传入 的协程不会马上启动,而是直到某个地方用 调用了用它创建的任务:
用控制结构组合协程
一系列线性执行的协程可以很方便的使用关键字 管理。对于复杂的控制结构,例如一个协程等待其他几个协程并行完成,也可以用 中的工具实现。
等待多个协程
将一个操作分成许多部分并分别执行它们是很常见的场景。例如,下载多个远程资源,或查询远程 API。在执行顺序无关紧要,并且可能存在任意数量的操作的情况下, 可以用于暂停一个协程,直到其他后台操作完成:
在内部, 使用一个集合来保存它创建的任务实例,所以任务的执行顺序是无序的。 的返回值是一个包含两个集合的元组,第一个保存了状态为 的任务,第二个保存了状态为 的任务。
调用 时如果指定了 参数,才会出现状态为 的任务:
这些状态为 的任务应被取消或者继续等待它们完成。事件循环继续运行时这些任务将继续执行,如果 函数的完成被认为所有操作都已经终止了,那这样的结果是不正确的;如果在事件循环结束时仍未完成这些任务,则会生成警告。所以有必要在 函数结束后取消所有状态为 的任务。
收集协程的结果
如果要执行的多个协程已经被定义好,并且只关心它们的结果,那么 是一种比较好的收集结果的方法:
创建的任务不会公开,因此无法取消。返回值是一个结果列表,顺序与传递给 的参数的顺序相同,与实际完成的顺序无关:
在任务完成后做一些事
是一个生成器,它管理当作参数传递给它的协程列表的执行,每次迭代都会产生一个执行完的协程。与 一样, 也不保证顺序;与 不同的是它不会等到所有后台操作完成后才可以执行其它操作:
这个例子启动了几个协程,这些协程以它们开始顺序的相反顺序结束。当生成器被消耗时,循环使用 等待协程的结果:
参考资料
https://pymotw.com/3/asyncio/tasks.html
https://pymotw.com/3/asyncio/control.html
领取专属 10元无门槛券
私享最新 技术干货