Python 的 asyncio 类似于 C++ 的 Boost.Asio。

异步 IO,就是你发起一个 IO 操作,不用等它结束,可以继续做其他事情,当它结束时,你会得到通知。

Asyncio 是并发(concurrency)的一种方式。对 Python 来说,并发还可以通过线程(threading)和多进程(multiprocessing)来实现。

Asyncio 并不能带来真正的并行(parallelism)。当然,因为 GIL(全局解释器锁)的存在,Python 的多线程也不能带来真正的并行。

可交给 asyncio 执行的任务,称为协程(coroutine)。一个协程可以放弃执行,把机会让给其它协程(即 yield from 或 await)。

定义协程

协程的定义,需要使用 async def 语句。

do_some_work 便是一个协程。

准确来说,do_some_work 是一个协程函数,可以通过 asyncio.iscoroutinefunction 来验证:

这个协程什么都没做,我们让它睡眠几秒,以模拟实际的工作量 :

在解释 await 之前,有必要说明一下协程可以做哪些事。协程可以:

asyncio.sleep 也是一个协程,所以 await asyncio.sleep(x) 就是等待另一个协程。可参见 asyncio.sleep 的文档:

运行协程

调用协程函数,协程并不会开始运行,只是返回一个协程对象,可以通过 asyncio.iscoroutine 来验证:

此处还会引发一条警告:

要让这个协程对象运行的话,有两种方式:

简单来说,只有 loop 运行了,协程才可能运行。

下面先拿到当前线程缺省的 loop ,然后把协程对象交给 loop.run_until_complete,协程对象随后会在 loop 里得到运行。

run_until_complete 是一个阻塞(blocking)调用,直到协程运行结束,它才返回。这一点从函数名不难看出。

run_until_complete 的参数是一个 future,但是我们这里传给它的却是协程对象,之所以能这样,是因为它在内部做了检查,通过 ensure_future 函数把协程对象包装(wrap)成了 future。所以,我们可以写得更明显一些:

完整代码:

运行结果:

回调

假如协程是一个 IO 的读操作,等它读完数据后,我们希望得到通知,以便下一步数据的处理。这一需求可以通过往 future 添加回调来实现。

多个协程

实际项目中,往往有多个协程,同时在一个 loop 里运行。为了把多个协程交给 loop,需要借助 asyncio.gather 函数。

或者先把协程存在列表里:

运行结果:

这两个协程是并发运行的,所以等待的时间不是 1 + 3 = 4 秒,而是以耗时较长的那个协程为准。

参考函数 gather 的文档:

发现也可以传 futures 给它:

gather 起聚合的作用,把多个 futures 包装成单个 future,因为 loop.run_until_complete 只接受单个 future。

run_until_complete 和 run_forever

我们一直通过 run_until_complete 来运行 loop ,等到 future 完成,run_until_complete 也就返回了。

输出:

现在改用 run_forever:

输出:

三秒钟过后,future 结束,但是程序并不会退出。run_forever 会一直运行,直到 stop 被调用,但是你不能像下面这样调 stop:

run_forever 不返回,stop 永远也不会被调用。所以,只能在协程中调 stop:

这样并非没有问题,假如有多个协程在 loop 里运行:

第二个协程没结束,loop 就停止了——被先结束的那个协程给停掉的。

要解决这个问题,可以用 gather 把多个协程合并成一个 future,并添加回调,然后在回调里再去停止 loop。

其实这基本上就是 run_until_complete 的实现了,run_until_complete 在内部也是调用 run_forever。

Close Loop?

以上示例都没有调用 loop.close,好像也没有什么问题。所以到底要不要调 loop.close 呢?

简单来说,loop 只要不关闭,就还可以再运行。:

但是如果关闭了,就不能再运行了:

建议调用 loop.close,以彻底清理 loop 对象防止误用。

gather vs. wait

asyncio.gather 和 asyncio.wait 功能相似。

具体差别可请参见 StackOverflow 的讨论:Asyncio.gather vs asyncio.wait。

Timer

C++ Boost.Asio 提供了 IO 对象 timer,但是 Python 并没有原生支持 timer,不过可以用 asyncio.sleep 模拟。

python rq asyncio_Python 的异步 IO:Asyncio 简介相关推荐

  1. aiohttp 高并发web服务_【Python入门】50.异步IO之 asyncio实现异步操作

    摘要:如何通过asyncio实现异步IO:用aiohttp模块编写支持多用户高并发的服务器. *写在前面:为了更好的学习python,博主记录下自己的学习路程.本学习笔记基于廖雪峰的Python教程, ...

  2. python异步和多线程_Python 异步 IO(asyncio)、多进程、多线程性能对比

    IO 密集型应用 IO 密集型应用CPU等待IO时间远大于CPU 自身运行时间,太浪费:常见的 IO 密集型业务包括:浏览器交互.磁盘请求.网络爬虫.数据库请求等 image.png Python 世 ...

  3. Python学习笔记:异步IO(3)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  4. Python学习笔记:异步IO(2)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  5. python asyncio_Python 的异步 IO:Asyncio 简介

    原标题:Python 的异步 IO:Asyncio 简介 Python 的 asyncio 类似于 C++ 的 Boost.Asio. 异步 IO,就是你发起一个 IO 操作,不用等它结束,可以继续做 ...

  6. python rq asyncio_python异步IO-asyncio

    参考链接:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143209095 ...

  7. Python学习笔记:异步IO(1)

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  8. Python 高级编程和异步IO并发编程 --13_5 ThreadPoolExecutor 和asyncio完成阻塞io请求

    # 使用多线程:在协程中集成阻塞io import asyncio import socket import time from urllib.parse import urlparse from c ...

  9. Python 高级编程和异步IO并发编程 --13_6 asyncio模拟http请求

    # asyncio 没有提供http协议的接口 import asyncio import time from urllib.parse import urlparseasync def get_ur ...

最新文章

  1. 《JavaScript高级程序设计》心得笔记-----第四篇章
  2. UBUNTU衍生版制作,系统的封装
  3. SE16N新改表内容方法!!!
  4. ubuntu环境下php安装amqp扩展
  5. 关于Unity中NGUI的背包实现之Scrollview(基于Camera)
  6. Android SDK 目录说明
  7. HUAWEI nova 青春版闪速快充,让追剧不再断电
  8. php.ini 老薛,出现Allowed memory size of 134217728 bytes exhausted怎么办?
  9. 《零基础》MySQL NULL 值处理(二十一)
  10. 升级域控制器-从Windows 2012升级到2016案例之1
  11. Vuex初级入门及简单案例
  12. pyecharts制作交互式数据展示地图
  13. java并发编程实战读书笔记 ExecutorCompletionService
  14. 传智播客视频python视频爬虫
  15. ssm网上书城系统毕业设计-附源码180919
  16. 金万维异速联产品简介
  17. Solr Facet
  18. 超详细的 Wireshark 使用教程
  19. Redis-AKF/CAP原则
  20. Android平台架构简介

热门文章

  1. 施华洛世奇的少女水晶梦还能继续吗?
  2. python管道符_Python实现处理管道的方法
  3. mysql换数据存储路径,mysql查看和修改数据存储路径并转移数据
  4. 太阳的光和灯光有什么区别_墙体彩绘机UV(油性)和水性墨水怎么选择?有什么区别?...
  5. java构造字符缓冲区_java学习笔记 | 学步园
  6. 强网杯2021 BlueTeaming (内存取证)
  7. python教程:getattr函数和hasattr函数的用法
  8. Python:colorlog的三个例子
  9. C语言进制转换时自动扩展位?(原码、反码、补码)(打印%o、%x时会自动扩展到32位【负数先得到其十进制真实数值,再根据其真实数值得到八进制、十进制补码】)
  10. python绘制柱状图,如何改变柱状柱间距,如何设置横纵轴标签(绘制Intel Realsense D435深度误差柱状图)