python之异步编程

article/2025/8/26 8:12:39

一、异步编程概述

异步编程是一种并发编程的模式,其关注点是通过调度不同任务之间的执行和等待时间,通过减少处理器的闲置时间来达到减少整个程序的执行时间;异步编程跟同步编程模型最大的不同就是其任务的切换,当遇到一个需要等待长时间执行的任务的时候,我们可以切换到其他的任务执行;

与多线程和多进程编程模型相比,异步编程只是在同一个线程之内的的任务调度,无法充分利用多核CPU的优势,所以特别适合IO阻塞性任务;

python版本 3.9.5

二、python的异步框架模型

python提供了asyncio模块来支持异步编程,其中涉及到coroutines、event loops、futures三个重要概念;

event loops主要负责跟踪和调度所有异步任务,编排具体的某个时间点执行的任务;

coroutines是对具体执行任务的封装,是一个可以在执行中暂停并切换到event loops执行流程的特殊类型的函数;其一般还需要创建task才能被event loops调度;

futures负责承载coroutines的执行结果,其随着任务在event loops中的初始化而创建,并随着任务的执行来记录任务的执行状态;

异步编程框架的整个执行过程涉及三者的紧密协作;

首先event loops启动之后,会从任务队列获取第一个要执行的coroutine,并随之创建对应task和future;

然后随着task的执行,当遇到coroutine内部需要切换任务的地方,task的执行就会暂停并释放执行线程给event loop,event loop接着会获取下一个待执行的coroutine,并进行相关的初始化之后,执行这个task;

随着event loop执行完队列中的最后一个coroutine才会切换到第一个coroutine;

随着task的执行结束,event loops会将task清除出队列,对应的执行结果会同步到future中,这个过程会持续到所有的task执行结束;

在这里插入图片描述
三、顺序执行多个可重叠的任务

每个任务执行中间会暂停给定的时间,循序执行的时间就是每个任务执行的时间加和;

import timedef count_down(name, delay):indents = (ord(name) - ord('A')) * '\t'n = 3while n:time.sleep(delay)duration = time.perf_counter() - startprint('-' * 40)print(f'{duration:.4f} \t{indents}{name} = {n}')n -= 1start = time.perf_counter()count_down('A', 1)
count_down('B', 0.8)
count_down('C', 0.5)
print('-' * 40)
print('Done')# ----------------------------------------
# 1.0010 	A = 3
# ----------------------------------------
# 2.0019 	A = 2
# ----------------------------------------
# 3.0030 	A = 1
# ----------------------------------------
# 3.8040 		B = 3
# ----------------------------------------
# 4.6050 		B = 2
# ----------------------------------------
# 5.4059 		B = 1
# ----------------------------------------
# 5.9065 			C = 3
# ----------------------------------------
# 6.4072 			C = 2
# ----------------------------------------
# 6.9078 			C = 1
# ----------------------------------------
# Done

四、异步化同步代码

python在语法上提供了async、await两个关键字来简化将同步代码修改为异步;

async使用在函数的def关键字前边,标记这是一个coroutine函数;

await用在conroutine里边,用于标记需要暂停释放执行流程给event loops;

await 后边的表达式需要返回waitable的对象,例如conroutine、task、future等;

asyncio模块主要提供了操作event loop的方式;

我们可以通过async将count_down标记为coroutine,然后使用await和asyncio.sleep来实现异步的暂停,从而将控制权交给event loop;

async def count_down(name, delay, start):indents = (ord(name) - ord('A')) * '\t'n = 3while n:await asyncio.sleep(delay)duration = time.perf_counter() - startprint('-' * 40)print(f'{duration:.4f} \t{indents}{name} = {n}')n -= 1

我们定义一个异步的main方法,主要完成task的创建和等待任务执行结束;

async def main():start = time.perf_counter()tasks = [asyncio.create_task(count_down(name,delay,start)) for name, delay in [('A', 1),('B', 0.8),('C', 0.5)]]await asyncio.wait(tasks)print('-' * 40)print('Done')

执行我们可以看到时间已经变为了执行时间最长的任务的时间了;

asyncio.run(main())# ----------------------------------------
# 0.5010 			C = 3
# ----------------------------------------
# 0.8016 		B = 3
# ----------------------------------------
# 1.0011 	A = 3
# ----------------------------------------
# 1.0013 			C = 2
# ----------------------------------------
# 1.5021 			C = 1
# ----------------------------------------
# 1.6026 		B = 2
# ----------------------------------------
# 2.0025 	A = 2
# ----------------------------------------
# 2.4042 		B = 1
# ----------------------------------------
# 3.0038 	A = 1
# ----------------------------------------
# Done

五、使用多线程克服具体任务的异步限制

异步编程要求具体的任务必须是coroutine,也就是要求方法是异步的,否则只有任务执行完了,才能将控制权释放给event loop;

python中的concurent.futures提供了ThreadPoolExecutor和ProcessPoolExecutor,可以直接在异步编程中使用,从而可以在单独的线程或者进程至今任务;

import time
import asyncio
from concurrent.futures import ThreadPoolExecutordef count_down(name, delay, start):indents = (ord(name) - ord('A')) * '\t'n = 3while n:time.sleep(delay)duration = time.perf_counter() - startprint('-'*40)print(f'{duration:.4f} \t{indents}{name} = {n}')n -=1async def main():start = time.perf_counter()loop = asyncio.get_running_loop()executor = ThreadPoolExecutor(max_workers=3)fs = [loop.run_in_executor(executor, count_down, *args)  for args in [('A', 1, start), ('B', 0.8, start), ('C', 0.5, start)]]await asyncio.wait(fs)print('-'*40)print('Done.')asyncio.run(main())# ----------------------------------------
# 0.5087 			C = 3
# ----------------------------------------
# 0.8196 		B = 3
# ----------------------------------------
# 1.0073 	A = 3
# ----------------------------------------
# 1.0234 			C = 2
# ----------------------------------------
# 1.5350 			C = 1
# ----------------------------------------
# 1.6303 		B = 2
# ----------------------------------------
# 2.0193 	A = 2
# ----------------------------------------
# 2.4406 		B = 1
# ----------------------------------------
# 3.0210 	A = 1
# ----------------------------------------
# Done.

http://chatgpt.dhexx.cn/article/hKjpq31n.shtml

相关文章

[进阶] --- Python3 异步编程详解(史上最全篇)

[进阶] - Python3 异步编程详解:https://blog.csdn.net/lu8000/article/details/45025987 参考:http://aosabook.org/en/500L/a-web-crawler-with-asyncio-coroutines.html 木风卜雨:https://blog.csdn.net/lu8000 1 什么是异步编程 1.1 阻塞…

tp5框架添加数据

tp5添加数据 添加 (js部分) 添加(php部分) 删除(js部分)

TP5框架后台排序

在写TP5框架开发的官网时,遇见需要为列表按倒序排列,若从数据库直接取出ID会因为该ID不连续,造成用户阅读困难。 因此查找了解决该问题的方法,因为涉及到分页,所以利用分页解决该问题 后台方法 前端页面数据 上图为正…

TP5框架查询数据获取结果集为数组的办法

TP5框架查询数据获取结果集为数组的办法 title: TP5框架查询数据获取结果集为数组的办法 tags: [TP5,模型,结果集,数组] 众所周知,使用TP5框架查询数据时,返回的结果集一般为对象,例如: $data \app\home\model\User::select();打…

tp5框架开发RESTful风格接口例子

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/example440982/article/details/80328087 tp5框架开发RESTful风格接口例子 time: 2018/5/15 author:…

TP5框架学习心得————(TP5框架的下载与其的基本目录结构)

一个好的软件直接影响到了我们的学习效率 TP5实在TP3.2的基础上改进的,相对与其他的框架个人觉得更适合与我们中国人毕竟是我们中国人自主研发的,想要学习起来其实也不难,只要看懂手册结合手册用一些小demo实现增、删、改、查基本上也就算入门了。 第一步:下载TP5框架 在…

tp5 框架使用Redis缓存,详解

1.小皮配置下载redis环境 1.打开小皮软件,选择软件管理找到redis下载, 2.找到网站域名,点击管理选中PHP扩展,选中redis 3.在首页启动redis,并查看配置 一般我们在小皮内启动redis后,查看配置参数是否正确…

tp5框架实现登录功能

TP5框架实现登录功能 安装TP框架 使用最简单的安装方式,直接从官网下载解压,将压缩包里的文件复制到项目目录下。 管网地址:http://www.thinkphp.cn/down.html 安装完框架的目录如图所示 添加控制器 在application\index\controller目录…

TP5框架目录解析

|-application 应用目录(几乎整个项目的内容都写在这里)|-index(这里的文件夹tp5叫做模块-----一般是前台模块,也可以根据需要需求修改成其他(例如:home),需要修改配置文件,修改默认模块、控制器、操作) 【注】:TP5默认只有一个index文件(模块)和一个控制层(con…

tp5登出_tp 5框架实现登录,登出及session登录状态检测功能示例

本文实例讲述了tp 5框架实现登录,登出及session登录状态检测功能。共享给大家供大家参考,详细如下: 1,访问http://localhost/tp5/admin.php时,判断有没有登录: 想法:写一个父类,继承…

ThinkPhp5开发实战1:搭建环境配置TP5框架(持续更新收藏关注)

文章目录 前言一、下载thinkphp5.0.10和安装本地环境二、下载H-UI后端模板三、静态文件引入四、创建后台页面首页 前言 php框架有助于促进快速应用开发,不仅节省时间,有助于建立更稳定的应用,而且,减少了重复代码。本文章采用图文…

SAP中会计科目删除相关知识点

一、考虑实际业务情况及科目删除的必要性或替代方案。如科目锁定可以满足业务需求的情况下,尽量不删除。 二、无业务数据的科目删除; 通过事务OBR2来执行科目删除。但前提是科目建立后没有任务过账业务数据。在OBR2的帮助信息中有相关描述。 三、删除标…

SAP 会计科目表并存时会计科目映射

会计科目表相关总结,查看:SAP会计科目表(Charts of Accounts)_王小磊的博客-CSDN博客_sap 科目表 会计科目维护T-CODE: FS00( FSP0 FSS0) 映射关系: 【一】运营科目表和国家科目表同时启用 国家科目表中的会计科目…

计算机软件属于生产资产吗,制造费用属于资产类科目吗?

摘要: 本文给各位税务会计带来的是制造费用属于资产类科目吗?相关的内容,在制造费用属于资产类科目吗?文章中给大家详细讲解了有关制造费用属于资产类科目吗?的会计税法知识。 制造费用属于资产类科目吗? 制…

Oracle EBS R12 创建会计科目失败诊断和处理

前言:Oracle EBS R12 财务系统中运维工作中比较常见的问题就是创建会计科目失败,本文对资产模块和应付模块创建会计科目的一般情况进行总结。 1.创建会计科目失败一般场景 1.1 期间未打开 当资产模块或应付模块的会计期间与总账模块的期间不一致时&#…

计算机维护费入什么会计科目,​系统维护费记入什么会计科目

系统维护费记入什么会计科目 答:开票: 借:管理费用--办公费 贷:现金或银行存款 借:应交税金--应交增值税(减免税) 贷:营业外收入 申报: 借:管理费用--办公费 贷:现金或银行存款 会计科目是对会计要素对象的具体内容进行分类核算的类目.会计对象的具体内容各有不同,管理要求也有…

计算机配件耗材发票科目有哪些,办公耗材属于什么会计科目

办公耗材属于什么会计科目 1、办公耗材属于一级科目管理费用,明细科目可写办公费。 2、办公耗材可依据所使用的部门来计入不同的科目, 管理部门使用的 借:管理费用--办公费 贷:银行存款/库存现金 销售部门使用的 借:销…

SAP 资产会计过账-总账科目的获取

资产创建 AS01 注意:资产的分类决定了 过账的对应的总账科目 SELECT SINGLE T095~KTANSW INTO TACCOUNTGL-GL_ACCOUNTFROM ANLAJOIN T095 ON ANLA~KTOGR T095~KTOGRWHERE ANLA~BUKRS PHEAD-BUKRS ANDANLA~ANLN1 GLWITEM-ASSET_NO ANDANLA~ANLN2 GLWITEM-SUB…

软件测试报告费计什么科目,软件记什么会计科目

1 软件记什么 会计 科目 会计学的研究对象包括会计的所有方面,如会计的性质、对象、职能、任务、方法、程序、组织,制度、技术等。会计学用自己特有的概念和理论,概括和总结它的研究对象。接下来小编就告诉你软件记什么会计科目。 根据《企业…