Asyncio异步编程笔记(纯人工整理)

写这篇笔记的初衷:由于现在ai大火,在agent学习,开发的时候几乎都离不开异步编程,但是网络上对于异步编程的讲解要么就是比较简略,要么就是比较晦涩难懂。很幸运的看到了一门比较优质的网课,这里就把我在看网课时记录和总结的笔记分享出来,都是自己纯手动整理的,包含了很丰富的代码实例,供大家一起交流学习。喜欢的话点个赞吧~

目录

协程

事件循环

await

Task对象

Future对象

uvloop


协程

协程,简而言之,就是通过一个线程实现代码块相互切换执行。

协程的意义:在一个线程中如果遇到IO等待时间,线程不会傻傻等,利用空闲时间再去干点其他事

实现协程的几种方法:

  1. yield关键字
  2. asyncio装饰器(3.4版本)
  3. async,await关键字(3.5版本后,推荐使用)

 1.yield关键字

def func1():
    yield 1;
    yield from func2() #跳到func2函数里面
    yield 2
def func2():
    yield 3
    yield 4
f1=func1()
for item in f1:#每次循环,执行里面的yield
    print(item)

如果一个函数里面有yield关键字,我们就认为是生成器函数,只要执行函数,返回的就是生成器

但是在真正实现协程,我们不会用这种方式,这里了解即可。

 2.asyncio装饰器(3.4版本)

import asyncio
@asyncio.coroutine
def func1():
    print(1)
    yield from asyncio.sleep(2) #遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(2)
@asyncio.coroutine
def func2():
    print(3)
    yield from asyncio.sleep(2) #遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(4)
tasks=[asyncio.ensure_future(func1()),
asyncio.ensure_future(func2())]
loop=asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

asyncio模块的特别之处在于遇到了yield from后面的IO操作,它不会傻傻地等,它会切换任务

实际应用:比如我要下载很多图片,在发送下载一张图片的请求后等待响应的时候,线程可以继续发送其它下载图片的请求,这时就可以节省很多时间

3.async,await关键字(3.5版本后,推荐使用)

import asyncio

async def func1():
    print(1)
    await asyncio.sleep(2) #遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(2)

async def func2():
    print(3)
    await asyncio.sleep(2) #遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(4)
tasks=[asyncio.ensure_future(func1()),
asyncio.ensure_future(func2())
]
loop=asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

这个完成的功能和asyncio装饰器其实是一样的,本质上就是把装饰器和yield from换成async 和 await,更加方便使用而已


事件循环

伪代码:
任务列表=[任务1,任务2...]
while True:
    for 可执行的任务 in 可执行的任务列表
        执行已就绪的任务
    for 已完成的任务 in 已完成的任务列表
        在任务列表中移除已完成的任务
    如果任务中的任务都完成,就终止循环

import asyncio
#去生成获取一个事件循环
loop=asyncio.get_event_loop()
#将任务放到任务列表
loop.run_until_complete(任务)

协程函数,定义函数时候 async def 函数名

协程对象执行 协程函数()得到的协程对象

async def func():
     pass
result=func() #这个result就是协程对象,但是func函数里面是不会执行的
loop=asyncio.get_event_loop()
loop.run_until_complete(result)
#3.7之后
asyncio.run(result)

如果想要运行协程函数内部代码,必须要将协程对象交给事件循环


await

await+可等待的对象(协程对象,Future,Task对象,IO等待)

示例1:

async def func():
    response=await asyncio.sleep(1)
    print("over")
    return "返回值"
asyncio.run(func())

示例2:

async def others():
    await asyncio.sleep(1)
    print("over")
    return "返回值"

async def func():
    response=await others()#await+协程对象
    print("IO请求结束,结果为:",response)
    
asyncio.run(func())

遇到IO操作挂起当前协程,等IO操作结束之后继续往下执行,当前协程挂起时,事件循环可以去执行其他任务示例3:(await+多个任务)

async def others():
    await asyncio.sleep(1)
    print("over")
    return "返回值"

async def func():
    response1=await others()#await+协程对象
    print("IO请求结束,结果为:",response1)
    response2=await others()#await+协程对象
    print("IO请求结束,结果为:",response2)
asyncio.run(func())

这里一定要注意,await其实就是在等,一定要等await后面的函数执行完成了,返回值了,才会执行下一句


Task对象

帮助在事件循环中添加多个任务

Task用于并发协程调度,通过asyncio.create_task(协程对象)(3.7之后)的方式创建Task对象,这样可以让协程加入事件循环中等待被调度执行。

示例1:

async def func():
    await asyncio.sleep(1)
    print("over")
    return "返回值"
async def main():
#创建task对象,将当前执行的func函数任务添加到事件循环
    task1=asyncio.create_task(func())
    task2=asyncio.create_task(func())
    ret1=await task1 #这里执行task1的时候,进入func函数,遇到IO(asyncio.sleep())的时候,会切换到另一个任务task2
    ret2=await task2

示例2(常写):

async def func():
    response=await asyncio.sleep(1)
    print("over")
    return "返回值"
async def main():
#创建task列表,将task对象都加到列表里面
    task_list=[
    asyncio.create_task(func())
    asyncio.create_task(func())
    ]
    done,pending=await asyncio.wait(task_list) #注意这里不能直接写 await task_list
    #done是一个集合,里面是task对象的返回值
asyncio.run(main())#这里事件循环已经创建了

Future对象

Task继承Future,Task对象内部await的结果是基于Future对象来的

示例1:

async def main():
#获取当前事件循环
    loop=asyncio.get_running_loop()
#创建一个任务,future对象,这个任务什么也不干
    fut=loop.create_future()
#等待任务最终结果(Future对象),没有结果则会一直等下去
    await fut

future对象用于等待结果

示例2:

async def set_after(fut):
    await asyncio.sleep(2)
    fut.set_result("1")#给future对象设置值,那么await就不再等待了
async def main():
#获取当前事件循环
    loop=asyncio.get_running_loop()
#创建一个任务,future对象,这个任务什么也不干
    fut=loop.create_future()
    await loop.create_task(set_after(fut))
#等待任务最终结果(Future对象),没有结果则会一直等下去
    data=await fut

uvloop

是asyncio的事件循环的替代方案,它的效率大于asyncio的效率

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())#将前面的替换成括号里的
#后面的代码和之前写代码的逻辑一致

uvicorn效率之所以高,本质上内部用的是uvloop


到这里就结束了,希望这篇笔记能帮助到大家,喜欢的话点个关注吧,我以后会继续分享相关知识的~

最全的ABB机器人手册资料汇总,包括以下内容:一、ABB常用说明书中文版集成视觉应用手册系统参数协同动作应用手册指令功能数据RAPID语言概览RAPID语言内核RS操作手册二、ABB机器人编程及指令手册ABB常用机器人技术参数abb机器人编程手册ABB机器人常用指令详解-中文()ABB机器人常用指令详解-中文()ABB机器人常用指令详解-中文()ABB机器人常用指令详解-中文()ABB机器人的程序数据Abb机器人调试步骤ABB机器人高级编程指令ABB机器人DEVICENET通信设置三、ABB机器人操作手册工业机器人实操与应用技巧ABB-低压产品选型手册ABB低压断路器选型手册ABB机器人操作手册-校准ABB机器人操作手册(中文版)ABB机器人基础及培训手册ABB机器人程序培训教材ABB机器人初级培训ABB机器人初级应用教学用演示ABB机器人弧焊培训ABB机器人基础ABB机器人培训ABB机器人培训教材ABB机器人学习资料四、ABB机器人项目式教学资料搬运应用弧焊应用码垛应用压铸取件应用ABB机器人教育实训平台展示五、ABB机器人周期维护资料00标准保养简介00ABB机器人标准保养IRB120机器人维护信息V1IRB360机器人维护信息V1IRB460机器人维护信息V1IRB660机器人维护信息V1IRB760机器人维护信息IRB1410机器人维护信息V1IRB1520机器人维护信息IRB1600机器人维护信息IRB2400机器人维护信息V1IRB2600机器人维护信息V1IRB4600机器人维护信息V1IRB6640机器人维护信息V1IRB6650机器人维护信息V1IRB7600机器人维护信息IRC5控制器维护信息六、ABB基础培训视频资料ABB机器人基础应用练习题trainningABB机器人合作伙伴专用密码是robotpartnerBasic Training培训包
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱写代码的倒霉蛋

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值