前言
Asyncio 不是多线程或多进程,而是并行运行代码。
JavaScript 中支持异步执行(浏览器,Nodejs,Electron 等)。在早期版本中,他们只是使用回调功能在异步操作完成后运行其他功能。但是它在 JavaScript 中创建了回调问题,因此在过去的十年中的某个时候,它们实现了相同的异步等待界面,我们在Python 3.6+ 中具有。该界面在使用相同的并行IO 效率的序列执行中寻找用户
使用代码
import asyncioimport time
def write(msg):
print(msg, flush=True)
async def say1():
await asyncio.sleep(1)
write("Hello from 1")
async def say2():
await asyncio.sleep(1)
write("Hello from 2")
write("start")
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(
say1(),
say2()
))
write("exit")
loop.close()
运行该代码,可以看到 Hello from 1 运行 1 秒后运行 Hello from 2:
$ python asyncoidemo2.pystart
Hello from 1
Hello from 2
exit
当 run_until_complete 运行 say() 函数,解释器会逐行执行该函数的内容。当碰到 await 之后,解释器开始异步操作:这个操作为了循环将完成一些内部回调操作,这个回调操作是对开发人员隐藏的。但是现在,say1 开始后,它立即将控制返回到事件循环。所以,它启动异步 sleep 和控制循环,然后循环实际上已经开始启动 say2 函数。
当第一次异步 sleep 运行 1秒后,进入内部回调执行 say1 协程,下一个操作是打印 Hello from 1。打印后,它再次返回到活动循环。同时,从第二次睡眠开始,循环获得了有关完成第二次睡眠的事件。
所以接下来 Hello from 2 打印,然后第二种方法也返回。 run_until_complete(gather(l1,l2,l3)) 将阻止所有 l1,l2,l3 Coroutines:
请注意,7 和 9 事件可能会交换 - 如果您多次运行代码,您可能会注意到 Hello from 1 打印在 Hello from 2之后。
- event_loop 事件循环:程序开启一个无限循环,把一些函数注册到事件循环上,当满足事件发生的时候,调用相应的协程函数
- coroutine 协程:协程对象,指一个使用 async 关键字定义的函数,它的调用不会立即执行函数,而是会返回一个协程对象。协程对象需要注册到事件循环,由事件循环调用。
- task 任务:一个协程对象就是一个原生可以挂起的函数,任务则是对协程进一步封装,其中包含了任务的各种状态
- future: 代表将来执行或没有执行的任务的结果。它和 task 上没有本质上的区别
- async/await 关键字:python3.5 用于定义协程的关键字,async 定义一个协程,await 用于挂起阻塞的异步调用接口。
asyncio 用途
当您需要并行多个 CPU 操作时。协程仅用于 IO 操作,例如某些 HTTP 客户端,例如 aiohttps 调用服务器。
CPU 计算操作,例如机器学习,在巨大的数列上循环,加快 CPU 运算。
Python中异步程序员工具套件中的最基本工具是新的关键字 async def,它用于声明异步的 coroutine 函数,其方式与定义正常同步函数的 def 相同。
总结
当我们使用 asyncio 时,我们会使用单个过程线程同时执行所有任务。asyncio是一个整洁的概念,并且每个数据科学家至少应该知道要使代码运行速度更快。了解该过程的良好工作知识也将帮助您了解即将到来的库,例如 Fastapi,Aiohttp,Aiofiles,Puppeteer 等。