当前位置: 首页 > news >正文

深入浅出:Python 中的异步编程与协程

引言

       大家好,今天我们来聊聊 异步编程协程,这是近年来编程语言领域中的热点话题之一,尤其在 Python 中,它作为一种全新的编程模型,已经成为处理 IO密集型 任务的强力工具。尽管很多人对异步编程望而却步,觉得它复杂难懂,但其实掌握了它,你就能感受到异步编程带来的速度提升,尤其是在高并发、网络爬虫、爬虫框架、聊天机器人等领域,异步编程简直是神器!

      所以,今天我们就从头开始,带你一步步搞懂异步编程和协程,带着你从基本概念到实际应用,通俗易懂又不失深度的讲解这项技术。

1. 什么是异步编程?

首先,来搞清楚异步编程同步编程到底有什么区别。

  • 同步编程:代码按照书写顺序逐行执行,每一行执行完,才会执行下一行。比如,你去餐厅点了菜,厨师开始做饭,直到你吃完饭才能结账离开,这个过程就叫做同步。

  • 异步编程:代码执行时,不会阻塞其他任务,可以让程序在等待某些任务的结果时,去做其他事情。继续以餐厅为例,当你点了菜后,厨师开始做饭,你可以先去刷会儿手机,聊天什么的,等做完了菜再叫你吃,这个过程就叫做异步。

      简单总结:同步是“做一件事等着做完”,而异步是“做事的时候,不等,去做其他事情”。如果我们把程序执行的时间浪费在等待 IO 操作(比如网络请求、数据库查询等)上,那就不如使用异步方式,让程序继续执行其他任务。

2. Python 中的异步编程

      在 Python 中,异步编程通常借助 asyncio 库来实现。asyncio 是 Python 的标准库之一,专门用于写异步 I/O 代码。Python 中的异步编程主要通过 协程 来实现。

2.1 什么是协程?

      在 Python 中,协程(Coroutine)是一种特殊的函数,它可以在执行过程中被暂停并在后续某个时间恢复执行。协程最常见的应用就是处理 I/O 操作(比如读取文件、发送网络请求等),因为这些操作可能需要等待一段时间,如果用同步代码,程序会一直等待,浪费了大量时间,而使用协程就能“挂起”执行并切换到其他任务。

你可以把协程想象成一个可以中途暂停并恢复的任务。这种灵活性非常适合处理大量并发 I/O 请求。

3. 如何写一个协程?

      Python 使用 asyncawait 关键字来定义和执行协程。让我们先看一个简单的例子:

import asyncioasync def hello_world():print("Hello")await asyncio.sleep(1)  # 模拟IO操作,暂停1秒print("World")# 运行协程
asyncio.run(hello_world())

      在上面的代码中:

  • async def 用来定义一个异步函数,也就是协程。
  • await 关键字用于在协程中调用另一个异步函数。在这个例子中,asyncio.sleep(1) 会暂停协程的执行 1 秒钟,模拟一个耗时的 I/O 操作。
  • asyncio.run() 用来启动协程。
4. 让多个协程并发执行

      协程的强大之处在于我们可以通过 asyncio 轻松地让多个任务并发执行。接下来,我们创建多个协程任务,让它们并行执行。

import asyncioasync def task(n):print(f"Task {n} started")await asyncio.sleep(2)print(f"Task {n} completed")async def main():# 创建多个任务并发执行tasks = [task(i) for i in range(5)]await asyncio.gather(*tasks)  # 等待所有任务完成asyncio.run(main())

      在上面的例子中,asyncio.gather(*tasks) 会将多个协程任务并行执行,而不是一个接一个地执行。这样,就能够在等待 I/O 操作的同时执行其他任务,充分利用时间。

5. 异步编程的优势

      异步编程最明显的优势就是它能够在高并发情况下提高程序的效率,尤其在处理大量 I/O 操作时(比如网络请求、文件读写等)。

  • 高效利用 CPU 资源:由于异步编程不会阻塞程序的执行,它允许 CPU 在等待 I/O 时去处理其他任务。
  • 减少延迟:在传统的同步方式中,IO 操作会造成大量的延迟,而异步编程可以在等待期间执行其他任务,从而减少整体的响应时间。
  • 处理大并发:使用异步编程,你可以在同一时间内启动成百上千的任务,而不会占用大量的系统资源。
6. 异步编程的陷阱

      尽管异步编程非常强大,但它也有一些潜在的陷阱,尤其是当你刚接触这个概念时:

  • 异步不适合所有任务:如果你的程序是 CPU 密集型的,异步编程反而可能导致性能下降。因为异步编程的优势主要体现在 I/O 密集型任务上。
  • 错误处理:在异步代码中,异常的处理和同步代码有些不同,特别是在并发执行的情况下,如何捕获并处理异常需要特别注意。
  • 调试困难:由于协程的执行是分散的,调试异步程序相对来说比同步程序更为复杂,尤其是在多个任务并行执行的情况下。
7. 异步与多线程的对比

      很多人会问,异步编程和多线程编程有何区别。简单来说:

  • 异步编程:是基于事件循环的方式,不需要多线程,适用于 I/O 密集型任务,通过非阻塞的方式提升并发度。
  • 多线程编程:是通过多个线程并行执行任务,适合计算密集型任务,但也带来了线程切换的开销和数据竞争等问题。

      异步编程的优势在于它能够在单个线程中高效地处理大量并发任务,而不会像多线程那样产生上下文切换的开销。

8. 实际应用案例:异步爬虫

      异步编程非常适合用来写爬虫程序。假设我们需要爬取多个网页,每个网页的请求都需要花费一定的时间,如果采用同步编程,程序就会一个接一个地等待每个网页的响应,效率低下。而使用异步编程,可以让爬虫程序在等待某个网页响应时,去请求其他网页。

下面是一个简单的异步爬虫示例:

import aiohttp
import asyncioasync def fetch_url(url):async with aiohttp.ClientSession() as session:async with session.get(url) as response:return await response.text()async def main():urls = ['http://example.com', 'http://example.org', 'http://example.net']tasks = [fetch_url(url) for url in urls]results = await asyncio.gather(*tasks)for result in results:print(result[:100])  # 打印前100个字符asyncio.run(main())

      在这个爬虫例子中,我们使用 aiohttp 库异步地请求多个网页,并且使用 asyncio.gather 来并行执行这些请求。这种方式比传统的同步爬虫效率更高,因为我们能够在等待网页响应时进行其他操作。

9. 总结

      通过本文的讲解,我们了解了 Python 中的异步编程以及协程的基本概念、应用场景以及注意事项。异步编程在处理大量 I/O 操作时能够显著提升程序的性能,特别是在高并发的情况下,它能够更高效地利用计算机资源。不过,异步编程并不是万灵药,适合 I/O 密集型任务,但对于 CPU 密集型任务,传统的多线程或多进程编程仍然更为高效。

      最后,异步编程的学习曲线可能有些陡峭,但一旦掌握了这一概念,它将为你开发高效、高性能的应用程序提供强大的支持!

相关文章:

深入浅出:Python 中的异步编程与协程

引言 大家好,今天我们来聊聊 异步编程 和 协程,这是近年来编程语言领域中的热点话题之一,尤其在 Python 中,它作为一种全新的编程模型,已经成为处理 IO密集型 任务的强力工具。尽管很多人对异步编程望而却步&#xff0…...

八大排序——简单选择排序

目录 1.1基本操作: 1.2动态图: 1.3代码: 代码解释 1. main 方法 2. selectSort 方法 示例运行过程 初始数组 每轮排序后的数组 最终排序结果 代码总结 1.1基本操作: 选择排序(select sorting)也…...

vue使用CSS布局技术,实现div定位到页面底部或顶部并居中功能

<template> <div > <div class"bottom-element"> 我在底部&#xff0c;并居中了 </div> </div> </template> 使用CSS布局技术&#xff0c;通过设置CSS属性来实现页面底部定位。 <style lang"scs…...

Jenkins 部署 之 Mac 一

Jenkins 部署 之 Mac 一 一.Jenkins 部署依赖 JDK 环境 查看 Mac JDK 环境&#xff0c;如果没有安装&#xff0c;先安装 打开终端输入命令:java -version Mac安装配置 JDK 二. 检查 HomeBrew 安装 检查 HomeBrew 是否安装&#xff0c;终端输入命令:brew -v Mac安装HomeB…...

【FastAPI 使用FastAPI和uvicorn来同时运行HTTP和HTTPS的Python应用程序】

在本文中&#xff0c;我们将介绍如何使用 FastAPI和uvicorn来同时运行HTTP和HTTPS的 Python应用程序。 简介 FastAPI是一个高性能的Web框架&#xff0c;可以用于构建快速、可靠的API。它基于Python的类型提示和异步支持&#xff0c;使得开发者可以轻松地编写出安全且高效的代…...

HCIA-路由器相关知识和面试问题

二、 路由器 2.1 关于路由器的知识 2.1.1 什么是路由器 路由器是一种网络层互联设备&#xff0c;主要用于连接多个逻辑上分开的网络&#xff0c;实现不同网络之间的数据路由和通信。它能根据网络层地址&#xff08;如 IP 地址&#xff09;来转发数据包&#xff0c;在网络中起…...

Docker+Jenkins自动化部署SpringBoot项目【详解git,jdk,maven,ssh配置等各种配置,附有示例+代码】

文章目录 DockerJenkins部署SpringBoot项目一.准备工作1.1安装jdk111.2安装Maven 二.Docker安装Jenkins2.1安装Docker2.2 安装Jenkins2.3进入jenkins 三.Jenkins设置3.1安装jenkins插件3.2全局工具配置全局配置jdk全局配置maven全局配置git 3.3 系统配置安装 Publish Over SSH …...

PCL 点云数学形态学操作(腐蚀)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 基本原理:使用结构元素(通常为滤波的窗口)的窗口模板作为处理单元,利用形态学中的膨胀与腐蚀相组合即可达到滤波的效果。 点云数据中的数学形态学运算其实和二维图像上的运算非常相似,图像上像素有x,y和亮度值…...

【设计模式】【行为型模式】观察者模式(Observer)

&#x1f44b;hi&#xff0c;我不是一名外包公司的员工&#xff0c;也不会偷吃茶水间的零食&#xff0c;我的梦想是能写高端CRUD &#x1f525; 2025本人正在沉淀中… 博客更新速度 &#x1f44d; 欢迎点赞、收藏、关注&#xff0c;跟上我的更新节奏 &#x1f3b5; 当你的天空突…...

RAGFlow和Dify对比

‌ RAGFlow和Dify都是基于大语言模型&#xff08;LLM&#xff09;的应用开发平台&#xff0c;具有相似的功能和应用场景&#xff0c;但它们在技术架构、部署要求和用户体验上存在一些差异。‌‌ RAGFlow和Dify对比 2025-02-13 22.08 RAGFlow‌ ‌技术栈‌&#xff1a;RAGFlow…...

AI前端开发:蓬勃发展的机遇与挑战

人工智能&#xff08;AI&#xff09;领域的飞速发展&#xff0c;正深刻地改变着我们的生活方式&#xff0c;也为技术人才&#xff0c;特别是AI代码生成领域的专业人士&#xff0c;带来了前所未有的机遇。而作为AI应用与用户之间桥梁的前端开发&#xff0c;其重要性更是日益凸显…...

结构型模式---代理模式

概念 代理模式是一种结构型模式&#xff0c;主要用于在客户端和接口之间添加一个中间层&#xff0c;用于在客户端和接口之间进行权限控制或者其他的中间层操作。 使用场景 1、延缓初始化&#xff0c;当我们偶尔需要使用一个重量级的服务对象&#xff0c;如果一直保持该对象的…...

Java面向对象一:相关概念

面向过程&面向对象 面向过程思想 步骤清晰简单&#xff0c;第一步做什么&#xff0c;第二步做什么… 面对过程适合处理一些较为简单的问题面向对象思想 物以类聚&#xff0c;分类的思维模式&#xff0c;思考问题首先会解决问题需要哪些分类&#xff0c;然后对这些分类进行…...

CEF132 编译指南 MacOS 篇 - depot_tools 安装与配置 (四)

1. 引言 在 CEF132&#xff08;Chromium Embedded Framework&#xff09;的编译过程中&#xff0c;depot_tools 扮演着举足轻重的角色。这套由 Chromium 项目精心打造的脚本和工具集&#xff0c;专门用于获取、管理和更新 Chromium 及其相关项目&#xff08;包括 CEF&#xff…...

React VS Vue

React 和 Vue 是目前最流行的两个前端框架&#xff0c;它们在设计理念、生态系统和开发体验上各有特点。以下是对 React 和 Vue 的全方位对比&#xff1a; 1. 核心设计理念 React 库而非框架&#xff1a;React 是一个用于构建 UI 的库&#xff0c;专注于视图层&#xff0c;其…...

伺服报警的含义

前言&#xff1a; 大家好&#xff0c;我是上位机马工&#xff0c;硕士毕业4年年入40万&#xff0c;目前在一家自动化公司担任软件经理&#xff0c;从事C#上位机软件开发8年以上&#xff01;我们在开发C#的运动控制程序的时候&#xff0c;一个必要的步骤就是设置伺服报警信号的…...

CSS 属性选择器详解与实战示例

CSS 属性选择器是 CSS 中非常强大且灵活的一类选择器&#xff0c;它能够根据 HTML 元素的属性和值来进行精准选中。在实际开发过程中&#xff0c;属性选择器不仅可以提高代码的可维护性&#xff0c;而且能够大大优化页面的样式控制。本文将结合菜鸟教程的示例&#xff0c;从基础…...

基于STM32、HAL库、HS12864(ST7920,并行接口)C语言程序设计

1、hs12864.h头文件: #ifndef __HS12864_H #define __HS12864_H #ifdef __cplusplus extern "C" {#endif #include "stm32l4xx_hal.h" // 控制线定义 - 根据实际硬件修改 #define HS12864_RS_GPIO_PORT GPIOC #define HS12864_RS_PIN GPIO_PI…...

Python练习11-20

题目&#xff1a;古典问题&#xff1a;有一对兔子&#xff0c;从出生后第3个月起每个月都生一对兔子&#xff0c;小兔子长到第三个月后每个月又生一对兔子&#xff0c;假如兔子都不死&#xff0c;问每个月的兔子总数为多少&#xff1f; 题目&#xff1a;判断101-200之间有多少…...

探索ELK 的魅力

在大数据时代&#xff0c;海量日志和数据的收集、存储、处理与可视化分析变得越来越重要。而 ELK 堆栈&#xff0c;由 Elasticsearch、Logstash、Beats 和 Kibana 组成&#xff0c;正是一个强大的开源解决方案&#xff0c;帮助开发者和运维人员高效管理和分析日志数据。本文将详…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...