Python 中的异步编程:从入门到实践

news2024/11/13 10:42:00

在现代编程实践中,异步编程已经成为一个不可或缺的技能,尤其是在处理高并发和I/O密集型应用时。Python,作为一种动态、解释型的高级编程语言,提供了强大的异步编程支持,使得开发者能够有效地编写高效、可扩展的应用程序。本文将详细介绍Python中的异步编程,包括其基本概念、工作原理、以及如何在实际项目中应用。

在这里插入图片描述

1. 异步编程简介

1.1 什么是异步编程

异步编程是一种编程范式,它允许程序在等待某些操作完成(如I/O操作、网络请求等)时,继续执行其他任务。这种编程方式可以显著提高程序的并发性和响应性,特别是在处理大量I/O操作时。

1.2 同步与异步的区别

在传统的同步编程中,程序的执行是线性的,即一个任务完成后,才会执行下一个任务。这种方式在处理I/O密集型任务时效率较低,因为程序在等待I/O操作完成时会处于空闲状态。

异步编程则允许程序在等待I/O操作完成时,继续执行其他任务。这样,当I/O操作完成时,程序可以立即处理结果,而不需要等待其他任务完成。

1.3 异步编程的优势

  • 提高性能:通过并发执行多个任务,异步编程可以提高程序的吞吐量和响应速度。
  • 资源利用率高:异步编程可以更有效地利用CPU和I/O资源,减少等待时间。
  • 更好的用户体验:在网络应用中,异步编程可以提供更流畅的用户体验,因为它允许程序在等待网络响应时继续处理其他任务。

2. Python中的异步编程

2.1 异步编程的历史

Python的异步编程能力最初是通过第三方库如TwistedTornado实现的。随着Python 3.4的发布,Python官方引入了asyncio库,这是一个用于编写单线程并发代码的库,它使用asyncawait语法来支持异步编程。

2.2 asyncio

asyncio是Python标准库中的一个模块,它提供了一个事件循环,用于调度协程(coroutine)的执行。协程是异步编程中的基本单位,它允许程序在等待I/O操作时挂起,直到I/O操作完成再恢复执行。

2.3 asyncawait关键字

  • async:用于定义一个协程函数。这个函数在调用时不会立即执行,而是返回一个协程对象。
  • await:用于在协程函数中等待另一个协程的完成。它允许协程在等待时释放控制权,让事件循环调度其他协程。

3. 异步编程的工作原理

3.1 事件循环

事件循环是异步编程的核心,它负责调度协程的执行。在Python中,事件循环由asyncio库提供。事件循环会不断地检查协程的状态,当一个协程被挂起时,事件循环会切换到其他协程,直到被挂起的协程可以继续执行。

3.2 协程的生命周期

一个协程的生命周期包括以下几个阶段:

  1. 创建:使用async def定义一个协程函数。
  2. 启动:调用协程函数,返回一个协程对象。
  3. 挂起:使用await挂起当前协程,等待另一个协程完成。
  4. 恢复:当挂起的协程可以继续执行时,事件循环会恢复它的执行。
  5. 完成:协程执行完毕,返回结果。

3.3 任务和任务组

asyncio中,任务(Task)是协程的一个封装,它允许协程在事件循环中并发执行。任务组(TaskGroup)是一组任务的集合,它允许你并行执行多个任务,并等待它们全部完成。

4. 实践异步编程

4.1 异步I/O操作

异步I/O操作是异步编程最常见的应用场景之一。在Python中,你可以使用aiohttp库来执行异步HTTP请求,或者使用aiofiles库来执行异步文件操作。

示例:异步HTTP请求
import aiohttp
import asyncio

async def fetch_data(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    url = "http://httpbin.org/get"
    html = await fetch_data(url)
    print(html)

asyncio.run(main())

4.2 异步网络编程

异步网络编程允许你同时处理多个网络连接。使用asyncio库,你可以轻松地创建异步服务器和客户端。

示例:异步TCP服务器
import asyncio

async def handle_client(reader, writer):
    data = await reader.read(100)
    message = data.decode().upper()
    addr = writer.get_extra_info('peername')

    print(f"Received {message} from {addr}")

    writer.write(data)
    await writer.drain()

    writer.close()

async def main():
    server = await asyncio.start_server(
        handle_client, '127.0.0.1', 8888)

    addr = server.sockets[0].getsockname()
    print(f'Serving on {addr}')

    async with server:
        await server.serve_forever()

asyncio.run(main())

4.3 异步数据库操作

许多数据库驱动支持异步操作,如aiomysqlaiopg。这些库允许你异步地执行数据库查询,而不会阻塞事件循环。

示例:异步数据库查询
import aiomysql
import asyncio

async def fetch_data():
    conn = await aiomysql.connect(host='127.0.0.1', port=3306,
                                  user='root', password='password',
                                  db='test', loop=asyncio.get_event_loop())
    async with conn.cursor() as cur:
        await cur.execute("SELECT * FROM users")
        print(cur.description)
        r = await cur.fetchall()
        for row in r:
            print(row)
    conn.close()

asyncio.run(fetch_data())

5. 异步编程的最佳实践

5.1 避免阻塞事件循环

在异步编程中,避免执行阻塞操作是非常重要的。阻塞操作会阻止事件循环,导致程序无法响应其他任务。如果需要执行阻塞操作,应该考虑使用线程池或进程池来异步执行。

5.2 正确处理异常

在异步编程中,正确处理异常是非常重要的。你应该使用try-except语句来捕获和处理协程中的异常,以避免程序崩溃。

5.3 使用适当的并发模型

根据你的应用需求选择合适的并发模型。对于I/O密集型任务,异步编程是一个很好的选择。但对于CPU密集型任务,你可能需要考虑使用多线程或多进程。

6. 异步编程的挑战

6.1 调试难度

异步编程的调试通常比同步编程更复杂,因为程序的执行顺序可能不是线性的。为了更好地调试异步程序,你可以使用专门的工具和库,如aiodebug

6.2 代码复杂性

异步编程可能会增加代码的复杂性,因为你需要管理协程的生命周期和并发执行的任务。为了降低复杂性,你应该使用清晰的代码结构和适当的抽象。

7. 结论

异步编程是提高Python程序性能和响应性的有效手段。通过理解异步编程的基本概念和工作原理,你可以编写出更高效、更可维护的代码。Python的asyncio库提供了强大的异步编程支持,使得异步编程变得简单和直观。通过实践和遵循最佳实践,你可以充分利用异步编程的优势,开发出高性能的应用程序。

8. 参考文献

  1. Python官方文档 - asyncio
  2. Python异步编程指南
  3. “Fluent Python” by Luciano Ramalho
  4. “Python Cookbook” by David Beazley and Brian K. Jones

通过本文的介绍,你应该对Python中的异步编程有了基本的了解。如果你对异步编程感兴趣,建议深入学习相关的概念和技术,并通过实践来提高你的技能。记住,异步编程是一个强大的工具,但也需要谨慎使用,以避免引入不必要的复杂性。

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

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

相关文章

虹科技术 | Linux环境再升级:PLIN驱动程序正式发布

Linux驱动程序领域再添新成员,PLIN驱动程序现已正式发布。这一新驱动程序为使用LIN接口的用户提供了一个便捷、高效的解决方案。本文将展示如何安装PLIN驱动程序,以及如何在Linux环境下进行基本的PLIN通信操作,确保您能够快速掌握并应用这一新…

寄存器二分频电路

verilog代码 module div2_clk ( input clk, input rst,output clk_div);reg clk_div_r; assign clk_div clk_div_r;always(posedge clk) beginif(rst)beginclk_div_r < 1b0;endelsebeginclk_di…

射击靶标检测系统源码分享

射击靶标检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

pytorch-AutoEncoders实战之VAE

目录 1. VAE回顾2. KL的计算公式3. 构建网络4. 模型训练 1. VAE回顾 VAE Variational Auto Encoder&#xff0c;变分自编码器。是一种常见的生成模型&#xff0c;属于无监督学习的范畴。它能够学习一个函数/模型&#xff0c;使得输出数据的分布尽可能的逼近原始数据分布&…

CCRC-CDO首席数据官:未成年人首次上网年龄持续降低

近日&#xff0c;中国社会科学院新闻与传播研究所联合社会科学文献出版社发布了《青少年蓝皮书&#xff1a;中国未成年人互联网运用报告(2024)》&#xff0c;该报告对中国未成年人的互联网使用情况进行了全面的研究和专项汇报。 调查数据透露&#xff0c;未成年人接触网络的年…

光耦选型 | 充电领域使用光耦型号推荐——晶体管光耦KL3H7

在充电领域&#xff0c;光耦作为一种常见的光电耦合器件&#xff0c;通常用于电气隔离、信号传输、电池保护和充电控制等方面。 电源气隔离&#xff1a;光耦可用于实现电源气隔离&#xff0c;将输入和输出电路进行隔离&#xff0c;提高系统的安全性和稳定性。 信号传输&#…

0基础也可以转行做产品经理吗?

转行成为产品经理&#xff0c;即使没有相关工作经验或技术背景&#xff0c;仍然是一个可行的目标。产品经理的职责多样&#xff0c;但成功的产品经理通常需要具备一系列的技能和素养&#xff0c;包括项目管理、市场分析、用户体验设计等。在没有相关经验的情况下&#xff0c;通…

动手学深度学习PyTorch 第 1 章 引言

在线电子书 深度学习介绍 安装 使用conda环境 conda create -n d2l-zh python3.8 pip安装需要的包 pip install jupyter d2l torch torchvision下载代码并执行 wget https://zh-v2.d2l.ai/d2l-zh.zip unzip d2l-zh.zip jupyter notebookpip install rise如果不想使用jupyt…

建筑企业有闲置资质怎么办?

在建筑行业中&#xff0c;企业可能会因为业务调整、市场变化或战略转型而拥有一些不再使用的资质。这些闲置的资质如果得不到合理处理&#xff0c;不仅会造成资源浪费&#xff0c;还可能影响企业的合规性。因此&#xff0c;建筑企业在面对闲置资质时&#xff0c;需要采取合适的…

《微信小程序实战(3) · 推广海报制作》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

C++ 9.19

练习&#xff1a;要求在堆区申请5个double类型的空间&#xff0c;用于存储5名学生的成绩。请自行封装函数完成 1> 空间的申请 2> 学生成绩的录入 3> 学生成绩的输出 4> 学生成绩进行降序排序 5> 释放申请的空间 主程序中用于测试上述函数 #include<ios…

选址模型 | 基于混沌模拟退火粒子群优化算法的电动汽车充电站选址与定容(Matlab)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于混沌模拟退火粒子群优化算法的电动汽车充电站选址与定容&#xff08;Matlab&#xff09; 问题建模&#xff1a;首先&#xff0c;需要将电动汽车充电站选址与定容问题进行数学建模&#xff0c;确定目标函数和约束…

双指针 -- 移动零、复写零、快乐数

目录 移动零 题解&#xff1a; 复写零 题解&#xff1a; 快乐数 题解&#xff1a; 盛最多水的容器 移动零 283. 移动零 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/move-zeroes/description/ 题解&#xff1a; 题目要求我们把数组中的 0 放…

大数据新视界 --大数据大厂之DevOps与大数据:加速数据驱动的业务发展

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

ReentrantLock实现原理

ReentrantLock是基于AQS实现的可重入锁&#xff0c;比synchronized更灵活&#xff0c;可以设置超时时间&#xff0c;可以中断&#xff0c;支持公平和非公平锁两种方式。公平锁获取锁的方式&#xff1a; 主要就是这三步 第一步&#xff1a;tryAcquire 先尝试获得锁 先获取state&…

Flux【真人模型】:高p高糊反向真实质感!网图风格的Lora模型,超逼真的AI美女大模型!

大家好&#xff0c;我是画画的小强 今天和大家分享一款基于Flux训练的网图风格的lora模型&#xff1a;墨幽-F.1-Lora-网图&#xff0c;该Lora模型由墨幽团队出品&#xff0c;旨在生成高p高糊的反向真实质感图片&#xff0c;而非真实摄影图片。不过&#xff0c;在自己出图过程中…

Linux操作系统 进程(3)

接上文 Linux进程优先级之后&#xff0c;我们了解到僵尸进程与孤儿进程的形成原因&#xff0c;既然是因为父进程没有接收子进程的退出状态导致的&#xff0c;那么我们该如何去获取子进程的退出状态呢&#xff1f;那本篇文章将围绕这个问题来解释进程。 环境 &#xff1a; vsco…

更高效的搜索工具,国内免费好用的AI智能搜索引擎工具

搜索引擎是我们获取信息的重要渠道&#xff0c;然而由于搜索引擎搜索结果存在较多的广告以及一些无关内容&#xff0c;这使我们的搜索效率变得更低效。小编就和大家分享几款国内免费好用的AI智能搜索工具&#xff0c;提高搜索效率。 1.开搜AI搜索 开搜AI搜索是一款基于深度学…

【学术会议:中国杭州,机器学习和计算机应用面临的新的挑战问题和研究方向】第五届机器学习与计算机应用国际学术会议(ICMLCA 2024)

您的学术研究值得被更多人看到&#xff01; 在这里&#xff0c;我为您提供精准的会议推荐&#xff0c;包括水利土木工程、计算机科学、地球科学、机械自动化、材料与制造技术、经管金融、人文社科等主流学科相关领域的国际会议。快速的稿件录用和高效的检索服务将确保您的研究…

30个小米集团芯片工程师岗位面试真题

在竞争激烈的半导体行业&#xff0c;小米集团作为全球知名的科技公司&#xff0c;对于芯片工程师的选拔标准自然也是极为严格。本篇分享一份《30个小米集团芯片工程师岗位面试真题》&#xff0c;通过对这30道真题的深入分析&#xff0c;我们可以一窥小米对于芯片设计人才的期待…