深入理解同步与异步编程及协程管理在Python中的应用

文章目录

    • 1. 同步与异步函数的对比
      • 1.1 同步函数
      • 1.2 异步函数
      • 1.3 对比
    • 2. 管理多个协程与异常处理
      • 2.1 并发执行多个协程
      • 2.2 错误处理
      • 2.3 任务取消

本文将探索Python中同步与异步编程的基本概念及其区别。还会详细介绍如何使用asyncio库来有效管理协程,包括任务的创建、错误处理和取消等功能。


1. 同步与异步函数的对比

1.1 同步函数

在同步模式下,如果some_function()进行耗时的I/O操作,比如网络请求或文件读取,程序将在此函数执行期间停止执行,直到操作完成。

def fetch_data():
    data = some_sync_function()  # 耗时操作
    return data

# 同步调用
data = fetch_data()

这种模式下,程序完全阻塞直到some_sync_function()执行完成。

1.2 异步函数

使用asyncawait创建的异步函数可以在执行中暂停并继续执行,无需阻塞程序:

async def fetch_data():
    data = await some_async_function()  # 异步操作
    return data

在这种模式下,await关键字使得fetch_datasome_async_function()执行期间暂停,将控制权交还给事件循环,允许执行其他操作。

1.3 对比

特性同步编程异步编程
执行方式阻塞式执行非阻塞式执行
资源利用效率较低,CPU等待I/O高效,CPU可以处理其他任务
复杂性相对简单较复杂,需要理解事件循环
适用场景简单脚本、小工具I/O密集型应用,如Web服务器
控制流线性,易于理解需要使用回调、promises等
库/框架无特殊需求需要支持异步的库(如asyncio
性能受限于I/O等待时间可大幅提高响应速度和吞吐率
错误处理直接处理需要特殊机制处理异常

同步和异步的对比图
在这里插入图片描述

2. 管理多个协程与异常处理

在使用asyncio进行并发编程时,不仅需要管理多个协程的并发执行,同时也需要妥善处理可能出现的错误和取消正在运行的任务。

2.1 并发执行多个协程

asyncio.gather是一个非常实用的函数,它允许同时启动多个协程,并等待所有协程执行完成。这样可以有效地利用时间,因为它允许多个协程并行执行而非顺序执行。

import asyncio

async def count():
    print("One", end=' ')  # 确保在打印后不自动换行
    await asyncio.sleep(1)
    print("Two", end=' ')  # 同样不换行

async def main():
    await asyncio.gather(count(), count(), count())

asyncio.run(main())
# 输出:One One One Two Two Two 

count协程会先打印“One”,然后等待1秒,接着打印“Two”。由于使用了asyncio.gather,三个count协程会并行执行,因此总的等待时间仅为1秒,而不是三次各自等待1秒。

加餐:end是干嘛用的

默认情况下,print函数会在每次调用后添加一个换行符,但如果设置end参数为一个空字符串'',那么输出将不会在末尾添加换行符。

2.2 错误处理

asyncio中处理错误是确保程序健壮性和响应性的关键。错误处理通常通过使用try-except块来实现,这允许程序在遇到预期内的异常时优雅地恢复。

import asyncio

async def error_task():
    raise ValueError("Something went wrong!")

async def main():
    task = asyncio.create_task(error_task())
    try:
        await task
    except ValueError as e:
        print(f"Caught an error: {e}")

asyncio.run(main())
# 输出:Caught an error: Something went wrong!

在这个例子中,error_task协程故意抛出一个ValueError异常。在main函数中,使用try-except块来捕获并处理这个异常。这样的错误处理机制确保了即使在异步任务失败时,程序也能继续运行,从而提高了整体的容错性。

asyncio.create_task 简介

asyncio.create_task()函数用于并行运行协程。此函数将协程封装成一个Task对象,并安排其在事件循环中执行。

2.3 任务取消

asyncio中,取消任务是异步编程中的另一个重要方面,它允许开发者在任务不再需要时终止执行,从而释放资源。

import asyncio

async def cancellable_task():
    try:
        print("Task starts")
        await asyncio.sleep(10)  # 假设这是一个长时间运行的任务
        print("Task completed")
    except asyncio.CancelledError:
        print("Task was cancelled!")

async def main():
    task = asyncio.create_task(cancellable_task())
    await asyncio.sleep(1)  # 给任务一点时间开始执行
    task.cancel()  # 取消任务
    try:
        await task
    except asyncio.CancelledError:
        print("Caught cancellation in main")

asyncio.run(main())
# 输出:
# Task starts
# Task was cancelled!
# Caught cancellation in main

在这个例子中,cancellable_task开始执行后,通过调用task.cancel()来请求取消任务。任务中的asyncio.sleep调用会在收到取消请求时抛出一个asyncio.CancelledError。在任务的try-except块中捕获这个异常,可以执行任何必要的清理工作。在main函数中,等待任务完成,并处理可能由任务取消引发的异常。


参考:Synchronous vs Asynchronous Programming: Models, Differences, Use Cases
推荐: python 错误记录

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

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

相关文章

C++动态内存管理 解剖new/delete详细讲解(operator new,operator delete)

讨厌抄我作业和不让我抄作业的人 讨厌插队和不让我插队的人 讨厌用我东西和不让我用东西的人 讨厌借我钱和不借给我钱的人 讨厌开车加塞和不让我加塞的人 讨厌内卷和打扰我内卷的人 一、C中动态内存管理 1.new和delete操作内置类型 2.new和delete操作自定义类型 二、operat…

人生的关键在于思想、精神和心情

人生的关键在于思想、精神和心情, 努力让自己的思想明澈, 让自己的精神充实而有所支撑, 让自己每天都有一个豁达、平和、开朗的心情, 这很重要。

SQLite的知名用户(二十九)

返回:SQLite—系列文章目录 上一篇:SQLite作为应用程序文件格式(二十八) 下一篇:SQLite—系列文章目录 SQLite被数以百万计的应用程序使用 从字面上看,有数十亿次部署。 SQLite 是 当今世界。 下面显示了一些…

Taro-vue微信小程序用户隐私保护

Taro-vue微信小程序用户隐私保护 一、在 微信公众平台的【设置】- 【服务内容与声明】 ,设置用户隐私保护指引,添加项目需要的接口权限。 【用户隐私保护指引】提交之后,官方会进行审核。审核通过之后,对应的接口权限才会生效。 …

实现 Table 的增加和删除,不依赖后端数据回显

需求 删除前 删除后 分析 首先写一个 Table <a-card style"width:100%"><template#extra><a-button type"text" click"addSelectItem" style"margin-right: 5px">添加</a-button><a-button type&quo…

springboot源码解析(一):启动过程

springboot源码解析(一):启动过程 1、springboot的入口程序 SpringBootApplication public class StartupApplication {public static void main(String[] args) {SpringApplication.run(StartupApplication.class, args);} }当程序开始执行之后&#xff0c;会调用SpringAppli…

大话设计模式之单例模式

单例模式是一种创建型设计模式&#xff0c;它确保类只有一个实例&#xff0c;并提供一个全局访问点来访问该实例。 单例模式通常在以下情况下使用&#xff1a; 当一个类只能有一个实例&#xff0c;并且客户端需要访问该实例时。当该唯一实例需要被公开访问&#xff0c;以便在…

2022年团体程序设计天梯赛-总决赛 L1 -L2

目录 L1-1 今天我要赢 L1-2 种钻石 L1-3 谁能进图书馆 L1-4 拯救外星人 L1-5 试试手气 L1-6 斯德哥尔摩火车上的题 L1-7 机工士姆斯塔迪奥 L1-8 静静的推荐 L2-1 插松枝 L2-2 老板的作息表 L2-3 龙龙送外卖 L2-4 大众情人 L1-1 今天我要赢 分数 5 2018 年我们曾经出…

新游戏-开箱H5游戏【无限贝拉/疯狂骑士团】最新整理Linux手工服务端+详细搭建教程

小编教大家搭建游戏啦 一款H5奉上 先上图 然后再看教程 90GM基地&#xff1a;www.t1gm.com 默认解压密码&#xff1a;www.t1gm.com 本教程只限于技术研究使用&#xff0c;请勿用于商业用途。 本资源由90GM基地独家提供 90GM基地交流群&#xff1a;639140260 ★★★★…

朗思-我的家园正式上线:朗思科技Agent工具软件--人人拥有“Ai-机器人”

4月16日&#xff0c;朗思科技正式发布"朗思-我的家园"。朗思科技是国内领先的Ai Agent智能自动化工具软件产品及方案的提供商&#xff0c;始终坚持自主研发&#xff0c;全面支持国产信创&#xff0c;不断加快产品创新迭代。基于技术领先性和战略前瞻性&#xff0c;其…

MySQL Explan执行计划详解

Explan执行计划 首先我们采用explan执行计划 执行一条sql&#xff0c;发现返回了12个列&#xff0c;下面会详细解释每一列 1、ID列 id列的值是代表了select语句执行顺序&#xff0c;是和select相关联的&#xff1b;id列的值大的会优先执行&#xff0c;如果id列为空最后执行&a…

用html画一个睡觉的熊动画

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>睡觉的熊动画</title><link rel"stylesheet" href"./style.css"> </head><body><div id"contain…

通过抖音短视频获客 只需要六步

抖音是当前最受欢迎的短视频平台之一&#xff0c;拥有庞大的用户群体和强大的社交矩阵&#xff0c;已经成为企业打造品牌口碑和快速获客的一种有效方式。那么&#xff0c;如何利用抖音短视频快速获客&#xff0c;打造品牌口碑呢&#xff1f;小马识途营销顾问简要分析如下&#…

Vue+OpenLayers7入门到实战:OpenLayers加载wkt格式数据,OpenLayers解析wkt格式的要素数据并渲染到地图上

返回《Vue+OpenLayers7》专栏目录:Vue+OpenLayers7入门到实战 前言 本章介绍如何使用OpenLayers7在地图上加载并解析wkt格式数据,以及渲染wkt格式的要素数据到地图上的功能。 使用Point(点)、(LINESTRING)线,和(POLYGON)多变形的wkt数据进行演示。 wkt介绍请参考博主…

【模拟】Leetcode 提莫攻击

题目讲解 495. 提莫攻击 算法讲解 前后的两个数字之间的关系要么是相减之差 > 中毒时间 &#xff0c;要么反之 那即可通过示例&#xff0c;进行算法的模拟&#xff0c;得出上图的计算公式 class Solution { public:int findPoisonedDuration(vector<int>& time…

论文DOI号相关及在latex中添加DOI跳转

DOI与ISBN, ISSN的不同之处 图书和期刊内容都使用DOI。 与ISBN和ISSN不同的是&#xff0c;ISBN喝ISSN可以识别图书或期刊&#xff0c;DOI可以识别单个章节或单篇文章。 所以&#xff0c;如果要搜寻某本书籍&#xff0c;需要用到的是ISBN号&#xff1b;如果要搜寻某本期刊&…

ESXi 无法启动NTP守护进程

在VMware ESXi环境中如果遇到无法启动NTP&#xff08;Network Time Protocol&#xff09;守护进程的问题&#xff0c;可以通过以下步骤进行排查和解决&#xff1a; 步骤1&#xff1a;检查与修复配置文件 登录到ESXi Shell&#xff08;SSH&#xff09;。编辑 /etc/ntp.conf 配…

Boost电感的作用

Boost电感在Boost升压电路中起着关键的作用。Boost电路是一种DC-DC电源转换器&#xff0c;其主要功能是将低电压直流&#xff08;DC&#xff09;信号转换为高电压直流&#xff08;DC&#xff09;信号。Boost电感在这个过程中起着平滑电流、储存能量和提高电路效率的作用。 具体…

C++初级----list(STL)

1、 list介绍 1.1、 list介绍 1.list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 1. list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向 其前一…

文件操作;

目录 1.文件的打开与关闭&#xff1b; 打开文件&#xff1b; 关闭文件&#xff1b; 2.文件的打开方式&#xff1b; “r”&#xff08;只读&#xff09;&#xff1b; “w”&#xff08;只写&#xff09;&#xff1b; 3.文件的顺序读写&#xff1b; 字符输入函数fgetc 代…