###引言

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. SoapUI:mock service的简单使用
  2. 【技术综述】基于弱监督深度学习的图像分割方法综述​
  3. Numpy中np.dot()与np.matmul()的区别(矩阵乘积、矩阵乘法、矩阵相乘)
  4. Okhttp3中设置超时的方法
  5. ML.NET 终于在Jupyter NoteBook 上跑起来了
  6. c# 中关键字_C#中的“使用”关键字
  7. python理论知识选择题_Python基础自测题答案和基础知识梳理
  8. jQuery原理第一天
  9. 多线程同步执行,CountDownLatch使用
  10. robocopy 备份_Windows 7系统强大的复制命令robocopy的操作方法介绍
  11. ros 开源物体检测_ROS kinetic + Realsens D435i + ORK + LINEMOD 物体识别
  12. 电机扭矩计算机公式由来T=9950*P/
  13. fastboot刷机工具_红魔3/3S 刷机教程
  14. python 大数据入门教程
  15. ECCV 2022 | 基于去遮挡和移除的3D交互双手姿态估计
  16. python语言是干什么的-python语言可以干什么
  17. 顺序栈的基本操作(C++实现)
  18. 开放经济的宏观经济学:基本概念 - 异想天开
  19. 设置java栈(stack)和堆(heap)大小
  20. oracle出库成固定资产,OracleebsR12固定资产-FA.ppt

热门文章

  1. 用Html语言打开文件,html是什么文件 html文件如何打开?
  2. Ubuntu 怎么卸载自带的国际版 firefox,安装中国版的 firefox
  3. 图像超分辨率重建学习记录(一)
  4. iOS抓包工具Charles基本抓包步骤
  5. MAXScript脚本用于建筑可视化
  6. 如何让人形机器人“行稳致远”?这篇顶级期刊的论文提出了新方法
  7. 【学习OpenCV4】漫水填充算法使用总结
  8. 4.8 鞅-最优停时定理(Durrett)答案
  9. 淘宝店铺商品发布API(新)接口,店铺上传接口代码对接教程
  10. “ 奋斗者耕耘论坛 ” 商业计划书 | 内卷 | 大学生创业计划书 | 大创 | 创新杯项目 | 如何财富自由 | 怎么发财 | 赚钱方法