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=0
    for 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*j
    print("普通计算密集型任务完成:",datetime.datetime.fromtimestamp(time.time()))

def computer2():
    print("普通CPU密集型任务:",datetime.datetime.fromtimestamp(time.time()))
    sum=0
    for 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*j
    print("普通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 task3
    await task2
    await task

loop=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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

源代码防泄漏之沙盒技术分析

随着企业信息化的快速发展,对于单位来说,网络中包含了很多重要的信息资料,比如网络中积累和掌握了大量的研发数据、生产数据和运营信息等,组织不希望这些资料离开企业内部的网络环境,甚至不允许在网络外部传递与交流&a…

uniapp小程序控制页面元素滚动指定距离

要实现页面元素滚动,最好还是使用 scroll-view 来实现,官方文档地址:scroll-view | uni-app官网 通过设置scroll事件来实现滚动监听,当滚动的元素的时候,就会触发这个事件,并且事件里面包含有滚动距离&…

Star CCM+创建报告与监测

前言 结合前文介绍,创建衍生零部件的目的是为了监测创建的点或者面的数据变化。如Star CCM衍生零部件的创建介绍,创建完所需的点或者面后,下一步就是对创建的点、面进行监测。 一 报告类型介绍 在Star中,通过创建报告来对监测的…

你还在手动加好友?试试这款神器,释放双手自动添加!

你还在手动添加微信好友吗?尤其是在忙碌的时候,手动加好友不仅费时又很容易出错。试试这个自动添加好友神器——个微管理系统,释放你的双手,轻松拓展好友列表! 1、多号同时登录在线 系统支持多个微信号同时登录在线&…

Transformer - Self-Attention层的复杂度的计算

Transformer - Self-Attention层的复杂度的计算 flyfish 矩阵的维度 下面矩阵的维度是32即 3行,2列 6,10等都是矩阵里的元素 如果矩阵A的列数与矩阵B的行数相同,那么这两个矩阵可以相乘。即,若A是一个mn矩阵,B是一个np矩阵&am…

SpringBoot打包运行,没有主清单属性

java -jar zhoao1.jar运行程序报&#xff1a;没有主清单属性 在pom.xml加配置&#xff0c;在打包即可 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId>&…

GD32F103RCT6/GD32F303RCT6-UCOSIII底层移植(1)工程建立

本文章基于兆易创新GD32 MCU所提供的2.2.4版本库函数开发 后续项目主要在下面该专栏中发布&#xff1a; 手把手教你嵌入式国产化_不及你的温柔的博客-CSDN博客 感兴趣的点个关注收藏一下吧! 电机驱动开发可以跳转&#xff1a; 手把手教你嵌入式国产化-实战项目-无刷电机驱动&am…

【电路笔记】-有源低通滤波器

有源低通滤波器 文章目录 有源低通滤波器1、概述2、有源低通滤波器2.1 一阶低通滤波器2.2 带放大功能的有源低通滤波器3、有源低通滤波器示例4、二阶低通有源滤波器通过将基本的 RC 低通滤波器电路与运算放大器相结合,我们可以创建一个具有放大功能的有源低通滤波器电路。 1、…

84.网络游戏逆向分析与漏洞攻防-游戏技能系统分析-筛选与技能有关的数据包

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

寻求发展+兼顾陪读|企业高管赴美国乔治梅森大学做访问学者

E经理拟去美国访学&#xff0c;想达到3个目的&#xff1a;结合本专业方向&#xff0c;扩展至跨学科研究领域&#xff1b;考察市场&#xff0c;寻求新的发展契机&#xff1b;携孩子出国读书&#xff0c;兼顾陪读&#xff0c;并希望尽早出国。最终我们为其落实的乔治梅森大学访问…

大规模LiDAR数据处理

点云存在许多描述环境或建筑物等物体的 x、y、z 坐标。通过激光技术 (LiDAR) 获取的点云通常带有每个坐标的额外测量值和特征。例如&#xff0c;反射强度、回波次数、回波、扫描角度和 RGB 值。换句话说&#xff0c;点云本质上是大量的数据集。 在本文中&#xff0c;我们使用开…

怎样让猫给啥吃啥?生骨肉冻干拌粮哪有猫咪不吃的!

随着科学养猫的普及&#xff0c;生骨肉冻干喂养越来越受欢迎&#xff0c;生骨肉冻干喂养对猫的好处很多&#xff0c;它符合猫咪的天性&#xff0c;可以提供全面的营养&#xff0c;保持牙齿和牙龈的健康&#xff0c;还有助于维持健康的消化系统。然而&#xff0c;许多猫主人在选…

测试之路 - 精准而优雅

引子 这几年业内一直在做精准测试&#xff0c;大都使用工具 diff 代码改动、分析代码覆盖率这些平台集成的能力。 业务测试中&#xff0c;我们在技术设计和代码实现的基础上也做了一些精减和精准的测试实践&#xff0c;通过深入测试有针对的设计 case&#xff0c;发现隐藏问题…

Gini Impurity(基尼不纯度)

基尼不纯度&#xff1a;衡量集合的无序程度&#xff1b; 基尼不纯度 基尼不纯度&#xff1a;将来自集合的某种结果随机应用于某一数据项的预期误差率。 1、显然基尼不纯度越小&#xff0c;纯度越高&#xff0c;集合的有序程度越高&#xff0c;分类的效果越好&#xff1b; 2、…

Blog搭建:pycharm+虚拟环境+django

pycharm创建项目 在pycharm新建项目&#xff0c;选择Django 项目名称&#xff1a;自定义项目位置&#xff1a;自定义创建git&#xff1a;方便上传到github选择虚拟环境方式venvpython解释器位置&#xff0c;和版本&#xff0c;如果你没有下载他会跳转到不同版本的供你下载temp…

力扣82题删除排序链表中的重复元素

82题删除排序链表中的重复元素 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 题目分析 这个题需要返回已排序链表&#xff0c;我们需要考虑一种情况就是头结点为重复元素&…

大数据Spark教程从入门到精通第四篇:Spark快速上手

一&#xff1a;Spark快速上手 1&#xff1a;创建Maven项目 idea安装scala_idea scala插件-CSDN博客 代表了我们安装scala的maven环境已经准备好了&#xff0c;代码可以正常跑了

这个notebook集合,赞

这几天在Github上看到一个数据科学仓库&#xff0c;汇总了很多Python notebook代码&#xff0c;主要是数据方向。 项目地址&#xff1a; https://github.com/donnemartin/data-science-ipython-notebooks 其中包括了pandas、numpy、matplotlib、scikit-learn、tensorflow、sp…

学习Nginx(一):基础

介绍 Nginx是一个高性能的HTTP和反向代理的web服务器&#xff0c;它的设计重点是高并发、高性能和低内存消耗。它常被用于提供静态内容、负载均衡和作为Web服务器。 Nginx具有以下功能和特点&#xff1a; 静态文件服务&#xff1a;作为一个Web服务器&#xff0c;Nginx可以处…

5.2 操作系统安装必备知识

目前操作系统安装方式接近于全自动化&#xff0c;用户无需做过多操作就能完成操作系统安装。但是操作系统安装也有其复杂的一面&#xff0c;例如固件及分区表的不同就会导致操作系统安装失败。本节主要介绍系统安装的一些必备知识。 5.2.1 BIOS 概述 BIOS(Basic Input/Output …