概念
按照Python3的文档介绍
asyncio 是用来编写 并发 代码的库,使用 async/await 语法
通常用来处理IO密集型的任务,如爬虫(bushi)网络请求、文件读写等任务
要理解asyncio的运行模式,需要有以下的概念
协程coroutine只有被包装成会话task才可以被执行,所有task由事件循环event loop决定是否执行
Event Loop(事件循环)
Event loop 作为asyncio的控制中心,实际上是一个不断循环的机制,用来调度、挂起、唤醒并执行协程
当使用asyncio.run()时便会自动创建一个事件循环
Coroutine(协程)
协程函数(coroutine function)
使用async关键字可以使一个函数变成协程函数
比如编写一个普通函数
print_hello()def print_hello(): print("Hello")调用
print_hello()函数输出为Hello当把
def改成async def时async def print_hello(): print("Hello")它就变成了print_hello()就变成了协程函数
协程对象(coroutine object)
协程函数被调用的时候会返回协程对象
async def print_hello(): print("Hello") print(print_hello())输出结果为
<coroutine object print_hello at 0x7fdb21345b40>可以发现,直接调用协程函数并不会执行里面的代码(输出Hello),返回的结果是一个协程对象
Task(任务)
await可以让协程对象
基本用法
await
下面这是Python3文档给的代码例子
import asyncio
async def main():
print('Hello ...')
await asyncio.sleep(1)
print('... World!')
asyncio.run(main())
修改一下代码,让每次输出
import asyncio
from datetime import datetime
async def print_hello():
await asyncio.sleep(1)
print('Hello ...')
async def print_world():
await asyncio.sleep(1)
print('... World!')
async def main():
print(datetime.now().strftime("%H:%M:%S"))
await print_hello()
await print_world()
print(datetime.now().strftime("%H:%M:%S"))
asyncio.run(main())
执行后输出为
22:13:22
Hello …
… World!
22:13:24
可以看到代码花了2秒才执行完毕
代码可以分成两个部分,做了以下事情
asyncio.run()- 建立
event loop - 把
coroutine变成event loop里的第一个task - 寻找可执行的
task并运行
- 建立
main()- 使用
async进入async模式(进入event loop控制整个程序的状态) await把协程coroutine包装成会话task
- 使用
coroutine被包装成一个task,并且告知event loop
通知event loop,等待xxx()完成后才继续执行
yield,先执行其他task
所以传入asyncio.run()的参数实际是一个协程对象(coroutine object)
asyncio.create_task()
asyncio.gather()
参考
asyncio的概念概述
asyncio — 异步 I/O
协程与任务
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。