当前位置:
首页 > Python基础教程 >
-
Python3标准库:asyncio异步I/O、事件循环和并发工具(5)
async def main(num_phases):
print('starting main')
phases = [
phase(i)
for i in range(num_phases)
]
print('waiting for phases to complete')
completed, pending = await asyncio.wait(phases)
results = [t.result() for t in completed]
print('results: {!r}'.format(results))
event_loop = asyncio.get_event_loop()
try:
event_loop.run_until_complete(main(3))
finally:
event_loop.close()
在内部,wait()使用一个set来保存它创建的Task实例,这说明这些实例会按一种不可预知的顺序启动和完成。wait()的返回值是一个元组,包括两个集合,分别包括已完成和未完成的任务。
如果使用wait()时提供了一个超时值,那么达到这个超时时间后,将只保留未完成的操作。
- import asyncio
- async def phase(i):
- print('in phase {}'.format(i))
- try:
- await asyncio.sleep(0.1 * i)
- except asyncio.CancelledError:
- print('phase {} canceled'.format(i))
- raise
- else:
- print('done with phase {}'.format(i))
- return 'phase {} result'.format(i)
- async def main(num_phases):
- print('starting main')
- phases = [
- phase(i)
- for i in range(num_phases)
- ]
- print('waiting 0.1 for phases to complete')
- completed, pending = await asyncio.wait(phases, timeout=0.1)
- print('{} completed and {} pending'.format(
- len(completed), len(pending),
- ))
- # Cancel remaining tasks so they do not generate errors
- # as we exit without finishing them.
- if pending:
- print('canceling tasks')
- for t in pending:
- t.cancel()
- print('exiting main')
- event_loop = asyncio.get_event_loop()
- try:
- event_loop.run_until_complete(main(3))
- finally:
- event_loop.close()
其余的后台操作要显式地处理,这有多方面的原因。尽管wait()返回时未完成的任务是挂起的,但只要控制返回到事件循环它们就会恢复运行。如果没有另一个wait()调用,则将没有对象接收任务的输出;也就是说,任务会运行并消费资源,但不会带来任何好处。另外,如果程序退出时还有未完成的任务,那么asyncio会发出一个警告。这些警告可能打印到控制台上,应用的用户便会看到。因此,最好取消所有剩余的后台操作,或者使用wait()让它们结束运行。
1.6.2 从协程收集结果
如果后台阶段是明确的,而且这些阶段的结果很重要,那么gather()可能对等待多个操作很有用。
- import asyncio
- async def phase1():
- print('in phase1')
- await asyncio.sleep(2)
- print('done with phase1')
- return 'phase1 result'
- async def phase2():
- print('in phase2')
- await asyncio.sleep(1)
- print('done with phase2')
- return 'phase2 result'
- async def main():
- print('starting main')
- print('waiting for phases to complete')
- results = await asyncio.gather(
- phase1(),
- phase2(),
- )
- print('results: {!r}'.format(results))
- event_loop = asyncio.get_event_loop()
- try:
- event_loop.run_until_complete(main())
- finally:
- event_loop.close()
gather()创建的任务不会对外提供,所以无法将其取消。返回值是一个结果列表,结果的顺序与传入gather()的参数顺序相同,而不论后台操作实际上是按什么顺序完成的。
1.6.3 后台操作完成时进行处理
as_completed()是一个生成器,会管理指定的一个协程列表,并生成它们的结果,每个协程结束运行时一次生成一个结果。与wait()类似,as_completed()不能保证顺序,不过执行其他动作之前没有必要等待所有后台操作完成。
- import
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式