【异步编程】【解锁并发的力量: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 防御 随着业务流程变得越来越复杂,公司开始转向第三方来提高其提供关…

解析XML文件的几种方法

解析XML文件的几种方法 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将深入探讨在Java中解析XML文件的几种常用方法。XML(可扩展标记语言…

《每天5分钟用Flask搭建一个管理系统》 第6章:数据库集成

第6章:数据库集成 6.1 数据库的选择和配置 在Flask中集成数据库,首先需要选择一个数据库系统。常见的选择包括SQLite、MySQL、PostgreSQL等。选择后,需要配置数据库连接字符串。 示例代码:配置数据库 from flask import Flask…

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

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

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

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

使用JavaScript的indexOf方法

使用JavaScript的indexOf方法 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们来探讨JavaScript中的indexOf方法。indexOf方法是JavaScript中一个非常实…

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

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

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

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

Socket编程详解(二)核心代码讲解

本文对代码的讲解基于上一篇博客 快速链接 Socket编程详解(一)服务端与客户端的双向对话 小试牛刀1:委托声明的关键字和委托方法使用的方法名是不一样的名称 可读性:有时,委托的名称可能描述了它的用途或它在哪里被…

使用Swoole开发高性能的Web爬虫

使用swoole开发高性能的web爬虫 Web爬虫是一种自动化获取网络数据的工具,它可以在互联网上收集数据,并且可以被应用于各种不同的领域,如搜索引擎、数据分析、竞争对手分析等。随着互联网规模和数据量的快速增长,如何开发一个高性…

RequestMappingHandlerAdapter【Spring源码学习】

HandlerAdapter处理器适配器就是去调用处理器方法! HandlerAdapter // 解析RequestMapping注解 生成路径和控制器方法得映射关系 RequestMappingHandlerMapping requestMappingHandlerMapping context.getBean(RequestMappingHandlerMapping.class);// 查看生成的…

六、常用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")】…

「树莓派入门」树莓派基础06-Linux操作系统和编辑器的使用

本文主要介绍如何在树莓派上使用终端进行基本操作,包括文件的创建、查看、删除和移动,以及如何使用超级用户权限和切换用户。同时,也介绍了如何使用nano和vi编辑器编辑文件。 一、连接树莓派 通过SSH连接 确保树莓派的SSH服务已启动。在终端…

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…

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

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

驾驭Scala的网络之力:HTTP客户端与服务器实战指南

驾驭Scala的网络之力:HTTP客户端与服务器实战指南 在现代应用开发中,HTTP作为网络通信的基石,其重要性不言而喻。Scala,以其强大的函数式编程特性和类型系统,为构建高效、可靠的HTTP客户端和服务器提供了丰富的工具和…

2.ROS串口安装和调试

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

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

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