Python使用asyncio包实现异步编程

2024-05-15 20:36

本文主要是介绍Python使用asyncio包实现异步编程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 异步编程

  异步编程是一种编程范式,用于处理程序中需要等待异步操作完成后才能继续执行的情况。异步编程允许程序在执行耗时的操作时不被阻塞,而是在等待操作完成时继续执行其他任务。这对于处理诸如文件 I/O、网络请求、定时器等需要等待的操作非常有用。
在这里插入图片描述
使用异步编程通常可以带来以下好处:

  • 提高程序效率和性能:异步编程使得程序在执行耗时的 I/O 操作(如网络请求、文件读写、数据库查询等)时不会被阻塞,减少了等待时间,充分利用了系统资源。
  • 改善用户体验:在 Web 开发中,异步编程可以确保服务器在处理大量并发请求时能够快速地响应用户,从而提高了 Web 应用的响应速度和用户体验。

2 async/await和asyncio包

2.1 异步函数的定义

  在Python中实现异步函数的定义需要两个关键字(asyncawait)。

  • asyncasync关键字声明一个异步函数。它可以在执行过程中暂停并允许其他代码执行。当你调用一个异步函数时,它会立即返回一个协程对象而不是实际的结果。异步函数适用于执行耗时的I/O操作,例如网络请求、文件读写、数据库查询等。这些操作通常涉及到等待外部资源的响应或者数据的传输,而在等待的过程中,CPU可以执行其他任务,从而提高程序的效率。
  • awaitawait关键字在 Python 中用于等待一个异步操作完成。当调用异步函数时,使用await关键字可以暂时挂起当前的异步函数的执行,将CPU控制权还给事件循环(Event Loop)。接着事件循环可以将执行权转移到其他任务上,而不是一直等待当前的异步函数完成。当被await的异步操作完成后,事件循环会通知原来的异步函数,使得它可以继续执行后续的操作。

在Python中异步函数的定义需要同时满足以下两个条件:

  • 使用async def关键字声明函数。
  • 函数内部包含异步操作,并且使用了await关键字等待异步操作完成。如果一个函数中只使用了async def声明,但其中任何异步操作,也没有使用await关键字,那么它实际上就是一个普通的同步函数,而不是一个异步函数。

2.2 事件循环

  事件循环(Event Loop)是异步编程中负责管理和调度异步任务执行的机制。事件循环的工作原理类似于一个持续运行的循环,它在每一轮循环中都会执行以下几个步骤:

  • 等待任务就绪: 事件循环会等待所有注册的异步任务就绪,包括等待 I/O 操作完成、等待计时器超时等。
  • 选择就绪任务:一旦有任务就绪,事件循环会选择其中一个任务进行执行。
  • 执行任务:事件循环会执行所选择的就绪任务,直到任务完成或者遇到await关键字,需要暂时挂起任务的执行。
  • 挂起任务:如果任务遇到await关键字,它会将控制权交还给事件循环,并等待 await后面的异步操作完成。
  • 继续执行其他任务:在等待await的异步操作完成的过程中,事件循环会继续执行其他就绪的任务,从而实现了并发执行的效果。
  • 异步操作完成: 当一个 await 后面的异步操作完成后,事件循环会通知原来的任务,使得它可以继续执行后续的操作。

2.2 asyncio

asyncio包python中常用的异步编程框架,这里使用该框架完成一个简单的异步编程案例,具体如下:


import time
import datetime
import asyncio
async def async_read_file():print("async读文件开始:",datetime.datetime.fromtimestamp(time.time()))await asyncio.sleep(20)print("async读文件完成:",datetime.datetime.fromtimestamp(time.time()))def computer():print("普通计算密集型任务:",datetime.datetime.fromtimestamp(time.time()))sum=0for i in range(1000000):if i%250000==0 and i!=0:print("普通计算密集型任务正在执行:",datetime.datetime.fromtimestamp(time.time()))for j in range(500):sum+=i+j-2*jprint("普通计算密集型任务完成:",datetime.datetime.fromtimestamp(time.time()))def computer2():print("普通CPU密集型任务:",datetime.datetime.fromtimestamp(time.time()))sum=0for i in range(1000000):if i%250000==0 and i!=0:print("普通CPU密集型任务正在执行:",datetime.datetime.fromtimestamp(time.time()))for j in range(5000):sum+=i+j-2*jprint("普通CPU密集型任务完成:",datetime.datetime.fromtimestamp(time.time()))async def asy_main():task=loop.create_task(async_read_file()) # 创建一个任务,并添加到事件循环,等待执行task2=loop.run_in_executor(None,computer)# 将普通函数read_file添加到事件循环中,等待执行task3=loop.run_in_executor(None,computer2)# 将普通函数read_file2添加到事件循环中,等待执行await task3await task2await taskloop=asyncio.get_event_loop() # 创建一个事件循环
loop.run_until_complete(asy_main())

其执行结果如下:

普通计算密集型任务: 2024-05-15 18:29:19.702689
普通CPU密集型任务: 2024-05-15 18:29:19.708280
async读文件开始: 2024-05-15 18:29:19.738654
普通计算密集型任务正在执行: 2024-05-15 18:29:21.441072
普通计算密集型任务正在执行: 2024-05-15 18:29:23.192585
普通计算密集型任务正在执行: 2024-05-15 18:29:24.936979
普通计算密集型任务完成: 2024-05-15 18:29:26.712930
普通CPU密集型任务正在执行: 2024-05-15 18:29:32.539679
async读文件完成: 2024-05-15 18:29:39.752731
普通CPU密集型任务正在执行: 2024-05-15 18:29:41.813872
普通CPU密集型任务正在执行: 2024-05-15 18:29:51.103737
普通CPU密集型任务完成: 2024-05-15 18:30:00.433402

Tips:虽然当下的执行结果中写完成了computer()的计算,后完成了computer2()的计算,但多次执行上述程序的时候也出现了两个函数交替执行的结果。

参考资料

  1. https://cloud.tencent.com/developer/article/1795692

这篇关于Python使用asyncio包实现异步编程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/992852

相关文章

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

基于Python打造一个智能单词管理神器

《基于Python打造一个智能单词管理神器》这篇文章主要为大家详细介绍了如何使用Python打造一个智能单词管理神器,从查询到导出的一站式解决,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 项目概述:为什么需要这个工具2. 环境搭建与快速入门2.1 环境要求2.2 首次运行配置3. 核心功能使用指

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

利用Python打造一个Excel记账模板

《利用Python打造一个Excel记账模板》这篇文章主要为大家详细介绍了如何使用Python打造一个超实用的Excel记账模板,可以帮助大家高效管理财务,迈向财富自由之路,感兴趣的小伙伴快跟随小编一... 目录设置预算百分比超支标红预警记账模板功能介绍基础记账预算管理可视化分析摸鱼时间理财法碎片时间利用财

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows