python之asyncio异步编程

news/2025/3/13 17:04:09/文章来源:https://www.cnblogs.com/yewuqi/p/18770333

异步编程可以这样来理解

# 伪代码
任务列表=[任务1,任务2,任务3,..
while True:
  可执行的任务列表,已完成的任务列表 = 去任务列表中检查所有的任务,将'可执行'和'已                  完成"的任务返回
  for 就绪任务 in 可执行的任务列表:

    执行已就绪的任务
  for已完成的任务 in 已完成的任务列表:

    在任务列表中移除 已完成的任务
  如果 任务列表 中的任务都已完成,则终止循环

大概的代码如下:

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

  

协程函数,定义函数时 async def 函数名():  这样的函数就是携程函数

协程对象,执行 协程函数  就得到了协程对象.

async def test():#这就是一个协程函数passresult = test()
#这就是一个协程对象

  

需要注意的是:执行协程函数创建协程对象时,函数里的代码并不会像普通执行函数一样,立刻就执行.而是需要这样来执行

async def test():#这就是一个协程函数print("快来吧!")result = test()
#这就是一个协程对象
loop = asyncio.get_event_loop()
loop.run_until_complete(result)

 

在python3.7之前,我们一般通过

loop = asyncio.get_event_loop()
loop.run_until_complete(result)

来执行协程对象

但是呢,python3.7以后有了更方便的方法 asyncio.run(任务)

import asyncioasync def test():#这就是一个协程函数print("快来吧!")result = test()
#这就是一个协程对象
asyncio.run(result)  # 运行协程对象

  

下面我们来看await ,await就是等待对象得到值以后,再继续往下走下去,我们看代码来分析

import asyncio
async def other():print('切入了other')await asyncio.sleep(2)print('切走了other')return '从other返回的结果'async def test():print('切入了test')ret = await other()print('test执行完毕',ret)asyncio.run(test())
'''
切入了test
切入了other
切走了other
test执行完毕 从other返回的结果
'''

 

可以看出当test函数被执行的时候,他先切入了test,随后ret调用了other函数,等other函数执行完毕后,再继续执行了test函数剩余的内容.

我们来让other函数连续执行两次.

import asyncio
async def other():print('切入了other')await asyncio.sleep(2)print('切走了other')return '从other返回的结果'async def test():print('切入了test')ret = await other()print('test执行完毕',ret)ret2 = await other()print('test执行完毕',ret2)asyncio.run(test())
'''
切入了test
切入了other
切走了other
test执行完毕 从other返回的结果
切入了other
切走了other
test执行完毕 从other返回的结果
'''

  

 可以看出等第一次other函数执行完,才执行的第二次other函数,程序并没有在两个other之间跳跃,也就是说,如果执行到了await,他会耐心的等待程序执行完毕,有了结果,才继续往下执行.不要觉得await好像什么用都没有,实际上他的用处也很多的.后面我们会再讲.

下面我们来看 Task对象  task对象是用来并发调度协程,可以添加多个task对象用来调度.

import asyncio
async def other():print('切入了other')await asyncio.sleep(2)print('切走了other')return '从other返回的结果'
async def test():print('切入了test')# 创建两个task对象tast1 = asyncio.create_task(other())tast2 = asyncio.create_task(other())print('test执行完毕')ret1 = await tast1ret2 = await tast2print(ret1,ret2)asyncio.run(test())
'''
切入了test
test执行完毕
切入了other
切入了other
切走了other
切走了other
从other返回的结果 从other返回的结果
'''

  我们来看结果,首先切入了test,然后直接往下执行了test执行完毕,然后连续切入两次other,然后连续切出other.最后拿到了两个返回的结果.

后面两个await的作用是,当test协程执行完之前,让他等待这两个other执行结束,否则程序会直接跑完test然后就结束.我们很可能等不到other执行完毕.

针对task我们其实还有更方便的写法.

import asyncio
async def other():print('切入了other')await asyncio.sleep(2)print('切走了other')return '从other返回的结果'
async def test():print('切入了test')tasklist = [asyncio.create_task(other()),asyncio.create_task(other()),asyncio.create_task(other())]print('test执行完毕')ret = await asyncio.wait(tasklist)print(ret)asyncio.run(test())'''
切入了test
test执行完毕
切入了other
切入了other
切入了other
切走了other
切走了other
切走了other
({<Task finished name='Task-4' coro=<other() done, defined at g:\vscodefile\python\test\ostest.py:2> result='从other返回的结果'>, <Task finished name='Task-3' coro=<other() done, defined at g:\vscodefile\python\test\ostest.py:2> result='从other返回的结果'>, <Task finished name='Task-2' coro=<other() done, defined at g:\vscodefile\python\test\ostest.py:2> result='从other返回的结果'>}, set())
'''

  补充三点:第一  可以给每个task对象命名

    tasklist = [asyncio.create_task(other(),name='n1'),asyncio.create_task(other(),name='n2'),asyncio.create_task(other(),name='n3'),]
#这样做的好处是,在拿返回值的时候({<Task finished name='Task-4' coro=<other() done, defined at g:\vscodefile\python\test\ostest.py:2> result='从other返回的结果'>, <Task finished name='Task-3' coro=<other() done, defined at g:\vscodefile\python\test\ostest.py:2> result='从other返回的结果'>, <Task finished name='Task-2' coro=<other() done, defined at g:\vscodefile\python\test\ostest.py:2> result='从other返回的结果'>}, set())    集合总返回的name不再是task-4 taks-3 而是你命名的,这样比较好拿结果

  另外一点是当协程调度时,我们可以设定超时的时间

ret,penging = await asyncio.wait(tasklist,timeout=5)
#设置了timeout 我们需要用两个变量来接收调度返回值,ret是运行完的协程返回值,而pengding是未运行完的协程返回的值

  

最后 我们其实更倾向于用 ret = await asyncio.gather()来并发等待所有task结束

done = await asyncio.gather(*tasklist)#首先,这里得到的是一个列表
#['从other返回的结果', '从other返回的结果', '从other返回的结果'] 
#这样更方便我们拿返回值.
#其次,这里可以直接把task放进来执行,也可以直接把futere放进来执行,他会一次先把所有的futere转成task,交给event loop去调度执行,最后才await所有返回值全部拿到.

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/898247.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu git 上传项目代码

Ubuntu git 上传项目代码 记录使用实验室电脑第一次上传实验代码的过程。 配置SSH密钥 1、本机生成 RSA 密钥对 本机使用ssh-keygen -t rsa命令生成 RSA 密钥,前面步骤都忘记截图啦。根据生成的密钥所在目录,打开id_rsa.pub并复制。这里复制的是公钥。 2、github 配置 SSH KE…

打印机服务共享器

采购与财务,还是使用针式打印,为了方便用,以前购买了IP打印共享器。 某些原因,局域网改变,域更变了,IP肯也得改变。前辈们以前设置或是配置的打印机共享器,没有留下管理可用的信息。如上,固网HP-1007打印机共享器,只有重置啦,电源插口旁有一个“Init.”手上如果还有光…

数字先锋 | AI+政务,轻松跨语种!霍尔果斯政务服务升级蜕变

今年,义乌国际商贸城的一家袜子店火爆全网,商家通过搭载DeepSeek模型的AI视创工具,只需录制中文口型视频,即可通过系统自动生成阿拉伯语、西班牙语等多语种带货视频,将袜子生意做到了世界各地。 在全球化与数字化深度交织的今天,DeepSeek凭借自然语言处理尖端技术,不仅让…

25年湛江一模第19题(马尔可夫链 )

25年湛江一模第19题(马尔可夫链 )专题:概率+数列 题型:马尔可夫链 难度系数:★★★★题目 (25 年湛江一模第 19 题)甲参加了一场智力问答游戏,每轮游戏均有两类问题(难度系数较低的\(A\)类问题以及难度系数较高的\(B\)类问题)供选择,且每…

25 年湛江一模第8题(函数奇偶性+恒成立)

25 年湛江一模第8题(函数奇偶性+恒成立)专题:概率+数列 题型:马尔可夫链 难度系数:★★★★ 题目 (2025 年湛江一模第8题) 已知定义在\(\mathbf{R}\)上的函数\(f(x)\)为奇函数,且当\(x>0\)时,\(f(x)=e^{x}-a\),若\(\forall x \in \mathbf…

每美搭(1)

一、团队介绍 1.1 团队概况 1.1.1 博客展示链接 团队名:每美搭子们,组长博客链接 https://www.cnblogs.com/0623-k 1.1.2 团队项目描述 每美搭:每美搭是一款专注于服装搭配推荐的APP。它能精准获取用户个人基本体型、上传服装类型等多维度数据,结合地区天气、用户心情、服装…

嵌入向量计算示例

嵌入向量计算示例 1. 问题设定场景:电影推荐系统中用户对电影类型的偏好嵌入 输入特征:4种电影类型(动作片、喜剧片、科幻片、爱情片) 嵌入维度:n_e = 2 词汇大小:n_v = 42. 数据表示 (1)独热编码电影类型 独热编码向量动作片 [1, 0, 0, 0]喜剧片 [0, 1, 0, 0]科幻片 […

塔石串口服务器的工作模式有哪些

串口服务器通过支持多种工作模式,实现了串行接口与网络接口之间的数据透明传输,提供了灵活的网络通信解决方案。以下是串口服务器的几种常见工作模式:| TCP Server模式 在TCP Server模式下,串口服务器作为TCP服务器,等待客户端的连接请求。这种模式下,串口服务器会监听一…

【正点原子】全志T113-i开发板震撼上市!异核开发、工控设计方案!新品上市,限时低价!

【正点原子】全志T113-i开发板震撼上市!异核开发、工控设计方案!新品上市,限时低价!ATK-DLT113IS开发板是正点原子基于全志T113-i处理器而研发的一款用于嵌入式Linux领域的开发板,其拥有高性能、高可靠性、低成本和丰富的接口资源,适用于嵌入式系统开发!T113-i芯片框架 …

Stochastic Orders 理解和相关运算(_随时补充)

Recall数学里,用\(o\)和\(O\)表示the order the terms. \(a_n = o(1)\). \(a_n = O(1)\).Stochastic order notation 是一种用来表示随机变量序列概率收敛的速记方法。 \(O_p(1)\)依概率有界; \(o_p(1)\)依概率收敛到0. \(X_n= O_p(a_n)\Leftrightarrow \frac{X_n}{a_n} =O_p…

DCC控制器模型铁路-蓝牙版本

蓝牙版本: 该单元加上App提供了一个完整的DCC控制器,具有击败更昂贵系统的功能。物有所值,可靠,使用简单,定制系统,以匹配您的火车头花名册。 包括F1到F32功能按钮兼容最新的声音解码器 添加您自己的loco名称和函数标题。 -在Android设备(手机或平板电脑)上安装App 对于初…

jMeter的下载和安装

jMeter简介: JMeter 是一款由 Apache 软件基金会开发的开源性能测试工具,主要用于模拟高负载场景下的应用程序行为,帮助开发者评估系统的性能、稳定性和可靠性。 核心功能1. 协议支持广泛:支持 HTTP/HTTPS、FTP、JDBC、SOAP、REST、WebSocket 等多种协议,可对 Web 应用、A…