###引言

asyncio作为python协程的标准实现,使用事件循环驱动的协程实现并发,已在python3.4纳入标准库,本文是在使用asyncio过程中,基本使用和整理
概述:子程序或函数在程序执行过程中,通过栈实现的层级调用。而协程在内部执行时可以中断去执行别的子程序,可以简单理解协程作为轻量级的线程。

1.基本描述
1.event_loop事件循环:协程函数注册到事件循环上,会依次相应的执行,支持注册Future和task类型的对象
2.coroutine协程对象:async定义的函数,返回一个协程对象,函数的最终执行交给event_loop
3.future:是对协程的封装(提供了取消/回调等),代表一个未来对象,执行结束后会把最终结果设置到Future对象上,属于底层对象,日常开发使用task
4.task任务:是future的子类,对future再一次的封装

2.协程实现的几种方式?
- python2.X:利用生成器通过yield+send实现协程
- python3.4:利用asyncio+yield from实现协程
- python3.5:asyncio+async/await(比较熟悉)
- python3.7:引入了asyncio.create_task和asyncio.run两个高级接口

3.正确使用姿势

import time
import asyncioasync def do1():print("do1:Starting")await asyncio.sleep(1)print("do1:Ending")return "do1"async def do3():print("do3:Starting")await asyncio.sleep(3)print("do3:Ending")retunr "do3"async def main():# 方式1:通过wait/gather实现并发# done,pending = await asyncio.wait(do1(),do3()) return_1,return_3 = await asyncio.gather(do1(),do3())# 方式2:通过ensure_future或create_task创建任务,在await实现并发task1 = asyncio.ensure_future(do1())task3 = asyncio.ensure_future(do3())await task1await task3# 方式3:直接await不能实现并发await do1()await do3()def perf_(func):start = time.perf_counter()asyncio.run(func())print(f"{func.__name"花费:{time.perf_count()-start}})if __name__ =="__main__":perf_(main())

4.两种方案获取返回值

1.通过回调add_done_callback()
2.通过task.result()接口,若任务没有完成,result()不会阻塞去等待结果,而是直接抛出asyncio.InvalidStateError异常

one:回调


import asynciodef callback(future):print("返回值:",future.result())async def return_data():await asyncio.sleep(1)return "to be or not to be"if __name__ =="__main__":loop = asyncio.get_event_loop()task = loop.create_task(return_data())task.add_done_callback(callback)loop.run_until_complete(task)loop.close()

two:task

import asyncio
import timenow = lambda:time.perf_counter()async def do_something(t:int):print("嵌套waiting:",t)await asyncio.sleep(t)return f"嵌套Cose {t}s"# 1.main处理结果
async def main1():coroutines = [do_something(2) for t in range(1,100)]tasks = [asyncio.ensure_future(coroutine) for coroutine in coroutines]done,pending = await asyncio.wait(tasks)for task in done:print("返回结果1:",task.result())# 2.await返回
async def main2():coroutines = [do_something(2) for t in range(1,100)]tasks = [asyncio.ensure_future(coroutine) for coroutine in coroutines]return await asyncio.wait(tasks)# 3.gather
async def main3():coroutines = [do_something(2) for t in range(1,100)]tasks = [asyncio.ensure_future(coroutine) for coroutine in coroutines]return await asyncio.gather(*tasks)def show_perf(func):start_= now()loop = asyncio.get_event_loop()# 1.# loop.run_until_complete(func())# 2.# done,pending = loop.run_until_complete(func())# for task in done:#     print("返回结果2:",task.result())# 3.results = loop.run_until_complete(func())for result in results:print("返回结果3:",result)print("perf:",now()-start_)if __name__=="__main__":# show_perf(main1)# show_perf(main2)show_perf(main3)

5.不要使用asyncio.create_task创建后台任务
create_task存在的问题
cpython-issue
asyncio仅仅会保留对Task的弱引用weakref,而弱引用不会阻止对象被python垃圾回收机制回收,可能导致正在运行的task被回掉

# asyncio.create_task(back_task())
# task was destroyed but it is pending
# 解决方案是对创建的task强引用
task = asyncio.create_task(back_task())

6.其他说明

1. wait和gather的区别
wait:默认情况下,会等待全部任务完成,所以pending默认是空的,可以使用return_when参数来决定返回时机
return_when:ALL_COMPLETED(默认全部返回),FIRST_COMPLETED(完成一个返回),FIRST_EXCEPTION(异常一个返回)
done, pending = await asyncio.wait(tasks:list[task])  # 传入task列表,done为已完成的task列表
gather:返回task执行的结果
results = await asyncio.gather(*tasks)    # 传入多个task,可以使用*tasks1. get_event_loop和new_event_loop,set_event_loop区别
主线程:get_event_loop会创建一个event_loop,并且多次调用始终返回该loop
其他线程:get_event_loop会报错,正确的使用是 loop=asyncio.new_event_loop asyncio.set_event_loop(loop)3. asyncio.create_task vs asyncio.ensure_task vs loop.create_task
(1.都是创建task的方法,asyncio.create_task为3.7新增的高阶用法
(2.asyncio.create_task就是使用的loop.create_task
(3.loop.create_task的参数是coroutine
(4.asyncio.ensure_task可以是(coroutine/Future/awaitable对象[实现__await__方法])-coroutine对象:还是使用loop.creat_task-Future对象:直接返回-awaitable对象:会await这个对象的__await__方法,在执行一次ensure_task,最后返回task/future
4. asyncio.run
asyncio.run():为3.7新增的高级接口,隐式的创建loop去执行task,直接asyncio.run(main())
asyncio.create_task:为3.7新增的高级接口,创建任务

asyncio的正确使用姿势相关推荐

  1. 论机器学习的正确学习姿势

    论机器学习的正确学习姿势 策划 | 刘燕作者 | Caleb Kaiser翻译 | Sambodhi编辑 | Linda很多开发人员并没有机器学习领域的背景,在机器学习如火如荼的今天,没学过机器学习的 ...

  2. 什么叫取反_转载:CodeReview正确的姿势是什么?

    作者:微博是阿里孤尽 链接:https://www.zhihu.com/question/383079175/answer/1109655276 来源:知乎 著作权归作者所有.商业转载请联系作者获得授 ...

  3. class ts 扩展方法_ts类型声明文件的正确使用姿势

    ts类型声明文件的正确使用姿势 ts声明文件类型 npm install @types/jquery --save-dev 与npm一同发布 解释: package.json 中有 types 字段, ...

  4. java同步锁如何使用_java 同步锁(synchronized)的正确使用姿势

    关于线程安全,线程锁我们经常会用到,但你的使用姿势正确不,反正我用错了好长一段时间而不自知.所以有了这篇博客总结下线程锁的正确打开姿势 废话不说看例子 一,对整个方法进行加锁 1,对整个方法进行加锁, ...

  5. 直播预告|中台基石腾讯云TStack的正确使用姿势

    各位亲爱的小伙伴们,你们好啊~~ 他二哥技术直播又和大家见面了! 还记得在第一期的节目中,Sandy小姐姐和两位技术哥哥带我们见识了腾讯自研交换机的强大实力. (赶紧戳链接复习☝) 这次直播,他二哥邀 ...

  6. MongoDB系列:五、MongoDB Driver使用正确的姿势连接复制集

    MongoDB复制集(Replica Set)通过存储多份数据副本来保证数据的高可靠,通过自动的主备切换机制来保证服务的高可用.但需要注意的时,连接副本集的姿势如果不对,服务高可用将不复存在. 使用复 ...

  7. java 日志使用_Java日志正确使用姿势

    前言 关于日志,在大家的印象中都是比较简单的,只须引入了相关依赖包,剩下的事情就是在项目中"尽情"的打印我们需要的信息了.但是往往越简单的东西越容易让我们忽视,从而导致一些不该有的 ...

  8. Python re 库的正确使用姿势

    前提假设: 已经充分掌握 PCRE 风格正则表达式 熟读 re 库文档 Why 正则表达式的强大已不用我赘述,Python 对此的支持也是十分强大,只不过: re.search(pattern, st ...

  9. 索引的正确“打开姿势”

    本文分享自华为云社区<DWS 索引的正确"打开姿势">,原文作者:hoholy . 索引能干什么呢,一言以蔽之:查询加速.常见的索引有下面几种: 1. 常用索引介绍 1 ...

最新文章

  1. 编写c语言程序 斐波那契,C语言程序实现斐波那契数列的解题思路???
  2. linux系统文件介绍
  3. java json设置编码_我们如何用Java编码JSON对象?
  4. BotSharp v0.2 发布, 支持微信智能回复
  5. 出道50年+!乘风破浪的编程语言们,能二次翻红吗?
  6. mac下查看redis安装路径_干货!win10环境下Redis安装、启动教程
  7. ORACLE中BFILE字段的使用研究
  8. 网易云复盘:云计算前端这一年(AngularJS粉慎入)
  9. [转载]修改SDE权限造成无法在ArcMap中绘制图形的解决办法
  10. 计算机电脑基础程序,电脑程序入门知识
  11. C#两套WPF,看板和WPF工业组件
  12. 【线性代数之二】矩阵与行列式
  13. exchange服务器重装后,Exchange 服务器 2010 SP3 安装更新汇总 30补丁包后Exchange控制台初始化失败?...
  14. 什么是V2X?如何通过V2X技术实现5G智慧交通?(一)
  15. Excel字符函数(3):字符查找函数Find、Search
  16. docker下载及vulhub靶场
  17. 提交模式窗口后,刷新父窗口数据+获取frameset中各模块中数据
  18. Meeting Rooms II -- LeetCode
  19. 无线电能传输LCC-S拓扑/WPT MATLAB/simulink仿真模型
  20. 计算机应用学java吗_计算机应用技术都学什么

热门文章

  1. 火车运煤问题 - 增加一个简单算法实现
  2. C语言实现10只小猪称体重
  3. 计算机动画专业教学大纲,3d-Max动画制作课程教学大纲
  4. bilibili爬虫+数据分析
  5. nmap与zmap的使用
  6. 转DIY 3D激光扫描仪
  7. Python Appium移动端app自动化测试框架
  8. 模板、皮肤、主题的定义
  9. 理解Python并发编程一篇就够了 - 线程篇
  10. 固定资产折旧计算的方法