【异步编程】【解锁并发的力量:Python 异步编程指南】

目录

  • 前言
  • 一、异步编程的概念
    • 1-1、异步编程
    • 1-2、同步 vs 异步
    • 1-3、阻塞 vs 非阻塞
    • 1-4、并发 vs 并行
  • 二、Python 异步编程的主要模块
    • 2-1、asyncio
    • 2-2、async 和 await 关键字
    • 2-3、 aiohttp
  • 三、案例分析
    • 3-0、安装
    • 3-1、基本案例
    • 3-2、并发执行多个任务
    • 3-3、异常处理
    • 3-4、与队列结合
  • 总结


前言

Python 异步编程是一种编程方式,用于处理可以并发执行的任务,以提高程序的效率和性能。异步编程允许在一个线程中执行多个任务,通过在某些任务等待 I/O 操作(如文件读写、网络请求等)完成时切换到其他任务,从而更有效地利用 CPU 资源。

一、异步编程的概念

1-1、异步编程

异步编程: 是一种编程范式,允许程序在等待某些操作完成时不阻塞线程或进程,继续执行其他任务。这种方式使得资源利用更高效,特别是在 I/O 密集型操作(如网络请求、文件读写等)中表现尤为显著。

1-2、同步 vs 异步

同步 vs 异步

  • 同步:任务按顺序执行,一个任务未完成时,后续任务必须等待。这种方式直观但效率较低,尤其在处理 I/O 操作时。
  • 异步:任务可以并发执行,一个任务在等待时,其他任务仍可继续进行。这样可以提高资源利用率和程序的响应速度。

1-3、阻塞 vs 非阻塞

阻塞 vs 非阻塞

  • 阻塞操作:会使得程序等待操作完成,期间无法执行其他任务。例如,读取文件时,程序会等待文件完全读取后再继续执行。
  • 非阻塞操作:操作会立即返回,程序可以继续执行其他任务。例如,发起一个网络请求后,程序可以继续执行其他任务,等待请求完成时再处理结果。

1-4、并发 vs 并行

并发 vs 并行

  • 并发:在同一时间段内处理多个任务,不一定是同时进行,但看起来像是同时进行。
  • 并行:在同一时刻同时处理多个任务,通常需要多核处理器支持。

二、Python 异步编程的主要模块

2-1、asyncio

asyncio 是 Python 标准库中的一个模块,专门用于编写并发代码。它提供了事件循环、协程、任务和各种 I/O 操作的异步支持。

  • 事件循环(Event Loop):asyncio 的核心组件,负责调度和管理协程的执行。事件循环不断运行,检查并执行准备好的任务。
  • 协程(Coroutine):使用 async def 定义的函数,可以在等待某个操作完成时挂起并允许其他协程运行。
  • 任务(Task):由事件循环管理的协程,通过 asyncio.create_task() 创建,可以并发执行。
  • 未来对象(Future):表示一个异步操作的结果,通常不直接使用,而是通过任务和协程间接使用。

2-2、async 和 await 关键字

async 和 await 关键字

  • async:用于定义协程函数。协程函数是可以在执行过程中挂起并恢复的函数。
  • await:用于暂停协程的执行,等待某个异步操作完成,然后继续执行。await 后面可以跟随一个返回 awaitable 对象(如协程、任务或未来对象)的表达式。注意: 异步函数需要使用 await 关键字进行调用, 如果不使用await,调用异步函数只会返回一个协程对象,函数内部的异步操作不会实际执行。

2-3、 aiohttp

aiohttp 是一个用于构建异步 HTTP 客户端和服务器的库。它基于 asyncio 实现,允许在异步环境中进行高效的 HTTP 通信。

  • HTTP 客户端:使用 aiohttp 可以发起异步 HTTP 请求,不阻塞主线程,处理大量并发请求时性能优越。
  • HTTP 服务器:aiohttp 提供了构建异步 HTTP 服务器的能力,适用于高并发环境。

三、案例分析

3-0、安装

pip install asyncio

3-1、基本案例

概述: 使用await挂起协程的执行,即模拟的IO操作,直到被等待的任务完成。asyncio.run() 用于启动一个事件循环并运行协程。

import asyncioasync def fetch_data():print("Start fetching data...")await asyncio.sleep(2)  # 模拟 I/O 操作,实际应用中可以是网络请求或文件读写print("Data fetched.")return "Data"async def main():print("Main started")result = await fetch_data()  # 等待 fetch_data 完成print("Result:", result)print("Main finished")# 获取事件循环并运行 main 协程
asyncio.run(main())

输出:
在这里插入图片描述

3-2、并发执行多个任务

概述: 可以使用 asyncio.gather() 或 asyncio.create_task() 来并发执行多个任务

两个任务并发

import asyncioasync def task1():await asyncio.sleep(1)print("Task 1 completed")async def task2():await asyncio.sleep(2)print("Task 2 completed")async def main():tasks = [task1(), task2()]await asyncio.gather(*tasks)  # 并发执行所有任务asyncio.run(main())

输出:

在这里插入图片描述

多任务并发:

import time
import asyncio# 定义异步函数
async def hello():await asyncio.sleep(1)print('Hello World:%s' % time.time())async def main():tasks = [hello() for i in range(5)]await asyncio.gather(*tasks)if __name__ == '__main__':# 自动创建一个事件循环,运行传递给它的协程,并在运行结束后关闭事件循环。# 这种方法适合简单的脚本和程序,因为它隐藏了事件循环的管理细节。asyncio.run(main())

多任务并发:等价于上边的函数,但是更底层

import time
import asyncio# 定义异步函数
async def hello():await asyncio.sleep(1)print('Hello World:%s' % time.time())if __name__ == '__main__':loop = asyncio.get_event_loop()tasks = [hello() for i in range(5)]# 运行事件循环,直到传递的任务完成。# 我们可以把一些函数(通过 async 定义的函数,称为协程)注册到事件循环上,当满足事件发生的条件时,调用相应的协程函数。# asyncio.wait 和 asyncio.gather的功能类似,但可以更灵活地处理任务完成的顺序。loop.run_until_complete(asyncio.wait(tasks))

多任务并发总结:

  • 第二段代码使用 asyncio.run(),这是一个高层次的 API,简化了事件循环的创建、运行和关闭过程。
  • 第三段代码手动获取和管理事件循环,更低层次,可以提供更大的灵活性。

3-3、异常处理

概述: 异步函数中的异常处理与同步代码类似,但需要在协程中使用 try、except 块


import asyncioasync def faulty_task():await asyncio.sleep(1)raise ValueError("An error occurred!")async def main():try:await faulty_task()except ValueError as e:print("Caught an exception:", e)asyncio.run(main())

输出:
在这里插入图片描述

3-4、与队列结合

概述: 异步编程还支持与异步生成器、队列、锁等高级特性结合使用,以实现更复杂的并发逻辑。

import asyncioasync def producer(queue):for i in range(5):await asyncio.sleep(1)await queue.put(i)print(f"Produced {i}")async def consumer(queue):while True:item = await queue.get()if item is None:breakprint(f"Consumed {item}")queue.task_done()async def main():queue = asyncio.Queue()await asyncio.gather(producer(queue), consumer(queue))await queue.join()asyncio.run(main())

输出:
在这里插入图片描述


参考文章:
【测试开发】python系列教程:asyncio模块
理解python异步编程与简单实现asyncio

总结

🤣沉迷于DNF手游无法自拔。

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

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

相关文章

嵌入式Linux系统编程 — 5.1 uname、sysinfo、gethostname、sysconf函数查询系统信息

目录 1 uname函数获取内核名称和信息 1.1 Linux系统命令行 1.2 系统调用函数 2 sysinfo 函数 3 gethostname 函数 4 sysconf函数 1 uname函数获取内核名称和信息 1.1 Linux系统命令行 在Linux系统中,uname命令行工具可以显示关于当前操作系统的信息。这个命…

你还能顶几天?

A总:你还能顶几天? 汪汪队:顶到奉命撤退的那一天 A总:你在这守散钱点几十年了,从来没跟我提过任何的要求,难道你不困难吗? 汪汪队:有困难,但是我提了有什么用呢&#…

第三方服务提供商的五大风险

亚马逊如何应对网络安全挑战 关键网络安全统计数据和趋势 移动优先世界中安全和隐私策略 当今数字时代网络安全的重要性 用户无法停止犯安全错误的 3 个原因 首席安全官可能过于依赖 EDR/XDR 防御 随着业务流程变得越来越复杂,公司开始转向第三方来提高其提供关…

算法基础--------【图论】

图论(待完善) DFS:和回溯差不多 BFS:进while进行层序遍历 定义: 图论(Graph Theory)是研究图及其相关问题的数学理论。图由节点(顶点)和连接这些节点的边组成。图论的研究范围广泛,涉及路径、…

DNF手游鬼剑士攻略:全面解析流光星陨刀的获取与升级!云手机强力辅助!

《地下城与勇士》(DNF)手游是一款广受欢迎的多人在线角色扮演游戏,其中鬼剑士作为一个经典职业,因其强大的输出能力和炫酷的技能特效,吸引了众多玩家的青睐。在这篇攻略中,我们将详细介绍鬼剑士的一把重要武…

【Python报错】已解决 ModuleNotFoundError: No module named ‘transformers‘

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 引入 ModuleNotFoundError: No module named ‘transformers’ 是一个常见的错误,它表明你的Python环境中没有安装t…

如何用CSS样式实现一个优雅的渐变效果?

CSS渐变效果 CSS渐变(Gradients)是一种让两种或多种颜色平滑过渡的视觉效果,广泛应用于网页背景、按钮、边框等,以创造丰富的视觉体验。CSS提供了线性渐变(Linear Gradients)和径向渐变(Radial…

六、常用API ★ ✔

六、常用API 模块14.基础API第一章.String1.String介绍2.String的实现原理 ★private final char[] value;private final byte[] value; 3.String的创建 ★ (无参、字符串、字符数组、字节数组)4.String 面试题【String s new String("abc")】…

Django —— 用户名和密码配置

创建项目ProjectA: django-admin startproject ProjectA cd进入ProjectA文件夹运行项目: python manage.py runserver 0.0.0.0:8000 Starting development server at http://0.0.0.0:8000/Quit the server with CTRL-BREAK. 访问http://localhost:80…

智慧校园-档案管理系统总体概述

智慧校园档案管理系统,作为教育信息化进程中的重要一环,它运用现代信息技术的力量,彻底改变了传统档案管理的面貌,为学校档案资源的收集、整理、存储、检索与利用开辟了全新的途径。这一系统全面覆盖学生、教职工、教学科研及行政…

2.ROS串口安装和调试

首先安装串口依赖 sudo apt-get install ros-melodic-serial 其次安装串口调试助手 sudo apt-get install minicom 再赋予串口权限 sudo chmod 777 /dev/ttyTHS1 打开调试助手 sudo cutecom 硬件引脚图:

【算法专题--栈】栈的压入、弹出序列 -- 高频面试题(图文详解,小白一看就懂!!)

目录 一、前言 二、题目描述 三、解题方法 💧栈模拟法💧-- 双指针 ⭐ 解题思路 ⭐ 案例图解 四、总结与提炼 五、共勉 一、前言 栈的压入、弹出序列 这道题,可以说是--栈专题--,最经典的一道题,也是在…

前端通过ResizeObserver来监听dom大小动态渲染echarts

export const GlobalResizeObserver (function () {const ATTR_NAME global-resizeobserver-keyconst attrValueToCallback {}function antiShake(fn, delay, immediate false) {let timer null//不能用箭头函数return function () {//在时间内重复调用的时候需要清空之前…

Java 实现将List按照字符串(特定规则)排序

日常开发中我们通常会遇到将一个List按照特定的规则排序,例如我们需要将一个List按照 “广州市”, “深圳市”, “珠海市”, “汕头市” 的顺序排序,我们可以使用下述方式实现。 City实体类 import lombok.AllArgsConstructor; import lombok.Data; im…

如何使用飞书快捷指令无感记账,ios版

总结 很多人无法长期坚持记账,主要是每次消费需要打开手机软件,一系列繁琐的操作,导致过程中可能就忘了。 今天给大家带来飞书自动记账。 演示视频 点击查看:https://www.douyin.com/video/7312857946382241063 安装 下载快捷…

hive调优原理详解:案例解析参数配置(第17天)

系列文章目录 一、Hive常问面试函数(掌握) 二、Hive调优如何配置(重点) 文章目录 系列文章目录前言一、Hive函数(掌握)11、JSON数据处理12、炸裂函数13、高频面试题13.1 行转列13.2 列转行 14、开窗函数&a…

mac Canon打印机连接教程

官网下载安装驱动: 选择打印机类型和mac系统型号下载即可 Mac PS 打印机驱动程序 双击安装 系统偏好设置 点击“”添加: OK可打印玩耍!! 备注: 若需扫描,下载扫描程序: 备注:…

禁止浏览器对input的自动填充和填充提示(适用于谷歌、火狐、Edge(原IE浏览器)等常见浏览器)

目录 1.要解决的问题2.一技能:原生属性,小试牛刀3.二技能:傀儡input,瞒天过海4.三技能:JavaScript出击,直接开大5.九九八十一难,永远还有最后一难 写在前面: 如有转载,务…

ElasticSearch 和 MySQL的区别

MySQLElasticSearch 数据库(database)索引(index)数据表(table) 类型(type) 记录文档(document,json格式) 一、ES基础命令 1. ES cat查询命令 2.…

如何用一个二维码实现企业固定资产管理?

固定资产管理中普遍存在盘点难、家底不清、账实不一致、权责不清晰等问题。如果平时不规范化执行,年终面对上上下下、大大小小、成百上千件物资要进行盘点整理的时候,会是十分痛苦且低效的事情。 今天这篇文章就来给大家推荐几家便宜好用的二维码固定资…