一文读懂Asyncio

news2024/11/21 2:24:18

什么是Asyncio

        asyncio 是用来编写并发代码的库,使用async/await语法。

        asyncio 被用作多个提供高性能 Python 异步框架的基础,包括网络和网站服务,数据库连接库,分布式任务队列等等。

        asyncio 往往是构建 IO 密集型和高层级结构化网络代码的最佳选择。

线程和协程

        协程是一种比线程更加轻量级的存在

        线程:把需要执行的任务比作汽车,线程就像一条单行且只有一条道的高速公路,只有等前一辆车到达终点后面的车才能出发,如果其中一辆出了事情停在了路上,那么这俩车后面的车就只能原地等待直到它恢复并到达终点才能继续上路。

        协程:把需要执行的任务比作汽车,协程就像一条带应急车道的高速公路,如果汽车在中途出了问题就可以直接到一边的应急车道停下处理问题,下一辆车可以直接上路,简单来说就是可以通过程序控制哪辆车行驶,哪辆车在应急车道休息。

同步和异步

同步:意味着有序
异步:意味着无序

同步必须一件事情结束之后再进行下一件事,异步是可以在一件事情没结束就去处理另外一件事情了。

定义协程函数

# work()函数就是一个协程
async def work(x):
    peint(x)
    await asyncio.sleep(x)

# 验证协程函数
print(asyncio.iscoroutine(work(1)))

协程对象

协程函数() 得到的对象 

注意: res = work()创建协程对象,函数内部代码不会执行。如果要运行协程函数内部代码,必须要将协程对象交给事件循环来处理。 

# work()函数就是一个协程
async def work(x):
    peint(x)
    await asyncio.sleep(x)

res = work()

loop = asyncio.get_event_loop()

loop.run_until_complete(res) 

运行协程函数

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

print(asyncio.iscoroutine(work(3)))

# 去生成或获取一个事件循环
loop = asyncio.get_event_loop()
# run_until_complete 的参数是一个 future,但是我们这里传给它的却是协程对象
loop.run_until_complete(asyncio.ensure_future(do_some_work(3)))

多个协程

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

loop.run_until_complete(asyncio.gather(work(1), work(3)))
# 这两个协程是并发运行的,所以等待的时间不是 1 + 3 = 4 秒,而是以耗时较长的那个协程为准
# gather 起聚合的作用,把多个 futures 包装成单个 future,因为 loop.run_until_complete 只接受单个 future。

await关键字

        await后跟可等待对象,可等待对象包括协程对象、Future和Task对象,这些都是IO等待。等IO操作完成之后再继续往下执行,当前协程(任务)挂起时,事件循环可以执行其他协程(任务)。

        同一个协程任务中,多个await,会依次等待等待对象执行完成;不同协程任务中,遇到await会交替执行。 

案例1:

import asyncio


async def func1():
    print(1)
    await asyncio.sleep(2)
    print(2)
    return "func1"


async def test1():
    print("执行协程函数test1内部代码")
    res = await func1()
    print("IO请求结束test1,结果为: ", res)
    res = await func1()
    print("IO请求结束test1,结果为: ", res)

tasks = [
    asyncio.ensure_future(test1())
]


loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

案例2

import asyncio


async def func1():
    print(1)
    await asyncio.sleep(2)
    print(2)
    return "func1"


async def func2():
    print(3)
    await asyncio.sleep(2)
    print(4)
    return "func2"


async def test1():
    print("执行协程函数test1内部代码")
    res = await func1()
    print("IO请求结束test1,结果为: ", res)


async def test2():
    print("执行协程函数test2内部代码")
    res = await func2()
    print("IO请求结束test2,结果为: ", res)


tasks = [
    asyncio.ensure_future(test1()),
    asyncio.ensure_future(test2())
]


loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

task对象

Task被用来在事件循环中添加多个任务的。

当协程包装到具有asyncio.create_task()等函数的任务中时,会自动地添加到事件循环中等待被调度执行。除了使用asynico.create_task()函数以外,还可以用底层级的loop.create_create_task()或ensure_future()函数。 

案例1

import asyncio


async def func1(n):
    print(n)
    await asyncio.sleep(2)
    print(n)
    return f"func{n}"


async def main():
    print('开始')
	# 自动加入到事件循环里
    task1 = asyncio.create_task(func1(1))
    # 自动加入到事件循环里
    task2 = asyncio.create_task(func1(2))

    print('结束')
    res1 = await task1
    res2 = await task2
    print(res1, res2)


asyncio.run(main()) 

案例2

import asyncio


async def func1():
    print(1)
    await asyncio.sleep(2)
    print(2)
    return "func1"


async def main():
    print('开始')
    task_list = [
    	# 自动加入到事件循环里
        asyncio.create_task(func1(), name='task1'),
        # 自动加入到事件循环里
        asyncio.create_task(func1(), name='task2')
    ]
    print('结束')
    done, pending = await asyncio.wait(task_list, timeout=None)
    print(done)


asyncio.run(main()) 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

无人机覆盖路径规划综述

摘要:覆盖路径规划包括找到覆盖某个目标区域的每个点的路线。近年来,无人机已被应用于涉及地形覆盖的多个应用领域,如监视、智能农业、摄影测量、灾害管理、民事安全和野火跟踪等。本文旨在探索和分析文献中与覆盖路径规划问题中使用的不同方…

二叉树:已知先序中序求后序或者其他(秒解)

看图找规律哈,不明白的在评论区找我哦

【精选】600兆 保研资料包 文书+面经+择校择导经验 等等 干货满满

推免上岸学长精选保研资料包 资源简介 保研上岸某中9计算机专业学长精心整理的600多兆保研资料包,内容覆盖全面,一次将保研涉及到的面试PPT、个人陈述、中英文自我介绍、英语问题、保研常识、专家推荐信、联系导师邮件、往年保研经验贴&面经、面试…

苹果TF签名全称TestFlight签名,需要怎么做才可以上架呢?

如果你正在开发一个iOS应用并准备进行内测,TestFlight是苹果提供的一个免费的解决方案,它使开发者可以邀请用户参加应用的测试。以下是一步步的指南,教你如何利用TestFlight进行内测以便于应用后续可以顺利上架App Store。 1: 准备工作 在测…

【Openstack Train安装】九、Nova安装

Nova是OpenStack中最核心的组件,它负责根据需求提供虚拟机服务并管理虚拟机生命周期,包括虚拟机创建、虚拟机调度和热迁移等。 Nova的子组件包括nova-api、nova-compute、nova-scheduler、nova-conductor、nova-db、nova-console等等。 本文介绍Nova安装…

Mysql 不执行索引问题与优化

难以查找的隐藏问题 及 解决办法: 问题总结:

基于SSM的仓库管理系统的设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

11月29日作业

作业: 自己封装一个矩形类(Rect),拥有私有属性:宽度(width)、高度(height), 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void show(…

Python语言学习笔记之二(基础语法)

本课程对于有其它语言基础的开发人员可以参考和学习,同时也是记录下来,为个人学习使用,文档中有此不当之处,请谅解。 Python几种字符串的表示: 在Python中,字符串是一种基本的数据类型,可以使…

高并发架构设计方法:面对高并发,怎么对症下药?

Java全能学习面试指南:https://javaxiaobear.cn 我们知道,“高并发”是现在系统架构设计的核心关键词。一个架构师如果设计、开发的系统不支持高并发,那简直不好意思跟同行讨论。但事实上,在架构设计领域,高并发的历史…

Linux:可视化管理工具Webmin的安装

一、下载 地址:Webmin官网 我这里下载的是1.700-1版本 二、安装 1、在虚拟机上新建目录并安装软件 mkdir /opt/webmin rpm -ivh webmin-1.700-1.noarch.rpm2、修改webmin的root密码 /usr/libexec/webmin/changepass.pl /etc/webmin root 1234563、修改端口(可…

macbook电脑运行缓慢和卡顿内存怎么清理了?

假如你还在为“你的系统内存不足”的提示所困扰,或者你的Mac电脑突然运行缓慢和卡顿,那么你一般需要认真了解一下macbook内存怎么清理了? MacBook是功能强大的电脑,这点毫无疑问,但是它仍旧会随着时间推移变得运行缓慢。值得庆幸…

瑞云科技参与《数字孪生世界白皮书》编写,实时云渲染助力数字孪生

为了促进数字孪生技术的发展和应用,易知微与数字孪生世界企业联盟联合众多行业专家以及多家业内企业共同编写了《数字孪生世界白皮书(2023)》。该白皮书从数字孪生的综述、应用架构、核心技术、新型技术成果和重点行业应用等方面,…

visual studio 2022 更改字体和大小

工具--->选项 文本编辑器 输出窗口

DDoS高防IP到底是什么?

DDoS高防IP是提供一个带防御的IP,主要是针对网络中的DDoS攻击进行保护,是针对互联网服务器遭受大流量的DDoS攻击后,导致服务不可用的情况下,用户可以通过配置高防IP,将攻击流量引流到高防IP上,从而确保源站…

手把手教你在AutoDL上Qwen-7B-Chat WebDemo Qwen-7B-Chat 网络演示

手把手带你在AutoDL上Qwen-7B-Chat WebDemo Qwen-7B-Chat 网络演示 项目地址:https://github.com/datawhalechina/self-llm.git 如果大家有其他模型想要部署教程,可以来仓库提交issue哦~ 也可以自己提交PR! 如果觉得仓库不错的话欢迎star&…

矩阵快速幂及应用实战[C/C++]

矩阵快速幂 矩阵快速幂可以用来优化递推问题,如状态机DP,需要一丢丢线性代数里面矩阵的概念,只需要知道简单的矩阵乘法,结合我们普通的二分快速幂就能很快的掌握矩阵快速幂。 问题引入 三步问题。有个小孩正在上楼梯,楼…

什么是海外私人IP代理?是纯净独享的代理吗?

相信许多互联网工作者都遇到过IP禁令,比如网络抓取项目,使用共享代理服务器向网站发出第一个请求,但却您收到了禁令,这大部分是由于你的共享IP经过多人使用被禁用所致。 那么到底什么是私人代理呢?它们是否适合您的情…

【刷题】链表

链表 206. 反转链表 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1] 示例 2: 输入:head [1,2] 输出:[2,1] 示…

进程间通信基础知识【Linux】——上篇

目录 一,理解进程之间的通信 1. 进程间通信目的 2. 进程间通信的技术背景 3,常见的进程间通信 二,管道 1. 尝试建立一个管道 管道的特点: 管道提供的访问控制: 2. 扩展:进程池 阶段一&#xff1a…