Python学习之-协程

news2024/11/27 21:36:05

前言:

在Python中,协程(coroutines)是利用生成器(generator)的特性,来实现并发编程的一种方式。从Python 3.5开始,通过引入async和await关键字,Python对异步IO提供了更原生的支持,使得协程成为了实现异步编程的首选方式。协程提供了比线程更轻量级的并发,它们在单线程内执行,但在等待IO操作(如网络请求、数据库查询等)的同时,可以让出控制权,这样CPU就可以去做其他的计算任务,提高了程序的执行效率和响应速度。

1. 协程的基本概念

异步IO (asyncio模块): Python的标准库asyncio是用来编写单线程并发代码使用的,它使用了事件循环来管理异步任务,通过async def声明协程函数,使用await来挂起对耗时操作的等待。
async: 声明一个协程函数,函数内可以使用await。
await: 在协程函数中用于等待另一个协程完成并获取其结果,同时让出控制权,使得其他协程可以运行。
事件循环(Event Loop): 程序的入口点,用于调度和管理所有的协程。

2. 协程的使用场景

协程可以用于一些需要频繁切换的操作,例如I/O操作、网络通信、GUI应用等。由于协程不需要线程切换和进程切换的开销,因此在这些场景中可以更高效地利用计算机资源。同时,协程还可以避免由于多线程和多进程带来的线程安全问题,使得代码更加简洁易读。

3. 协程的示例:

#!/usr/bin/env python
# coding=utf-8
# Author: Summer
# Time: 2024.04.1

import asyncio

async def main():
    print('Hello')
    await asyncio.sleep(1)
    print('world')

asyncio.run(main())
# 输出
# Hello
# world

这个简单的例子展示了一个异步协程的基本结构。main函数是一个协程,因为它是用async关键字定义的。在main协程中,await asyncio.sleep(1)这行代码让出了控制权,使得事件循环可以在这里挂起协程,去执行其他任务,在1秒后再回来继续执行。

再来举一个稍微复杂一点的例子,更好的说明协程的作用

#!/usr/bin/env python
# coding=utf-8
# Author: Summer
# Time: 2024.04.1

import asyncio
import aiohttp
import sys

if sys.platform == 'win32':
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())


async def save_content_to_file(url, session, file_name):
    async with session.get(url) as response:
        content = await response.text()
        with open(file_name, 'w', encoding='utf-8') as file:
            file.write(content)
        print(f"Content from {url} has been saved to {file_name}")


async def main(urls):
    async with aiohttp.ClientSession() as session:
        tasks = []
        for i, url in enumerate(urls):
            file_name = f'website_{i}.txt'
            task = asyncio.create_task(save_content_to_file(url, session, file_name))
            tasks.append(task)
        await asyncio.gather(*tasks)


# 准备一组URLs用于下载
urls = [
    'http://www.python.org',
    'https://www.baidu.com',
    'https://www.bing.com',
    # 更多URLs...
]

# 使用asyncio运行main协程及其所有子协程
asyncio.run(main(urls))

在上述代码中:
ave_content_to_file
这个协程负责获取特定URL的内容,并将其保存到本地文件中。具体步骤包括:
使用async with语法创建出一个异步上下文管理器,以session.get(url)的形式发送GET请求。这个操作是异步的,会挂起当前协程直到请求完成并返回响应对象。
通过await response.text()异步获取响应的文本内容。这会等待网络IO操作的完成,当内容被成功读取时,协程会继续执行。
通过普通的同步I/O操作with open(…) as file打开一个文件,文件名由file_name参数指定。
这个协程单独负责处理一个URL的下载和保存逻辑。
main
这个协程是程序的主入口。在这个协程中,执行了以下步骤:
创建一个共享的aiohttp.ClientSession(),在这个会话中,可以发送多个HTTP请求。整个会话使用async with包裹,确保会话在所有请求完成后被正确关闭。
初始化一个空的任务列表tasks。这是用来存放所有将要执行的save_content_to_file任务。
遍历给定的urls列表。对于列表中的每个URL,指定一个输出文件名file_name(按照website_{i}.txt的格式),创建一个save_content_to_file任务,并将这个任务添加到tasks列表中。
使用asyncio.gather(tasks)并发执行所有协程任务。asyncio.gather接收一个可迭代的协程列表,然后并发地运行它们,等待所有协程都运行完成。这里,星号操作符是将列表解包为函数的参数。
总结起来,main协程负责协调整个下载过程,为每个URL的下载创建异步任务,并监控它们直到全部完成。而save_content_to_file协程则关注于单个文件的下载和保存逻辑,将每个URL的内容保存到一个独立的文件中。
下面代码中的作用
调整事件循环策略(特别针对Windows)
如果你在Windows上遇到这个问题,并且确定问题是由Python 3.8及以后版本引入ProactorEventLoop导致的,你可以尝试改变事件循环的实现,切回到Python 3.7使用的SelectorEventLoop。在程序的开始执行:

if sys.platform == 'win32':
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

由于我的python版本是python3.8.2 比较老的版本,在3.8的版本之后我的windows系统上运行协程函数会报这个错误,
这是由于RuntimeError: Event loop is closed错误通常发生在异步程序的事件循环被不恰当地关闭或处理了之后没有适当地处理清理动作,这个问题特别常见于Windows系统上使用Python的asyncio库时。这是由于从Python 3.8开始,在Windows上,默认的事件循环被改变为ProactorEventLoop。ProactorEventLoop对于某些类型的异步I/O操作更高效,但也可能导致一些兼容性问题。
在这里插入图片描述

4. 协程、多线程、多进程的区别:

想了解多线程和多进程的也可以看我之前的文章:
https://blog.csdn.net/weixin_41238626/article/details/137191039
多进程
内存隔离:每个进程有自己独立的内存空间,进程间通信需要特殊的IPC机制,如管道、信号、共享内存等。
开销较大:进程的创建、销毁和切换比线程和协程都有较大的开销。
稳定性高:一个进程崩溃不会影响其他进程。
适用场景:适合于CPU密集型计算,可以利用多核CPU的优势。
多线程
共享内存:线程运行在同一个进程内,共享相同的内存空间,线程间通信相对容易。
开销适中:线程的创建、销毁和切换的开销小于进程但大于协程。
稳定性低:一个线程崩溃可能会影响同进程内的其他线程,甚至整个进程。
GIL(Global Interpreter Lock,全局解释器锁):在CPython解释器中,由于GIL的存在,同一时间只能有一个线程执行Python字节码,因此多线程在CPU密集型任务中不一定有效。
适用场景:适合I/O密集型任务,如文件读写、网络通信等,可以在等待I/O操作完成时进行其他线程的任务处理。
协程
轻量级:协程是用户态的线程,协程的切换由程序自己控制,没有内核态的介入,因此开销极小。
单线程内并发:协程在单个线程内实现并发,通过任务切换达到并发的效果,不存在线程切换的开销。
协作式调度:协程是协作式的,意味着一个协程主动挂起(yield)之后,另一个协程才能运行。
适用场景:适合高并发的I/O密集型任务,如网络请求、数据库查询等。
对比总结
开销:协程 < 多线程 < 多进程。协程没有线程上下文切换的开销,更适合执行大量的I/O密集型任务。
并发性:在I/O密集型应用中,协程可以实现高并发,而在CPU密集型任务中多进程能够更好地利用多核处理器。
内存和安全:多进程最安全(由于内存隔离),多线程次之,协程在单个线程内管理多个任务可能需要更细致的错误处理。
易用性:协程通常需要特定的语法支持(async/await),而多线程和多进程的概念相对容易理解。
不同的并发模型各有优缺点,适用的场景也不同。在实际的开发工作中,可能会根据任务的特性综合考虑使用不同的并发模型。

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

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

相关文章

脑机辅助推导算法

目录 一&#xff0c;背景 二&#xff0c;华容道中道 1&#xff0c;问题 2&#xff0c;告诉脑机如何编码一个正方形格子 3&#xff0c;让脑机汇总信息 4&#xff0c;观察图&#xff0c;得到启发式算法 5&#xff0c;根据启发式算法求出具体解 6&#xff0c;可视化 一&am…

【Blockchain】GameFi | NFT

Blockchain GameFiGameFi顶级项目TheSandbox&#xff1a;Decentraland&#xff1a;Axie Infinity&#xff1a; NFTNFT是如何工作的同质化和非同质化区块链协议NFT铸币 GameFi GameFi是游戏和金融的组合&#xff0c;它涉及区块链游戏&#xff0c;对玩家提供经济激励&#xff0c…

python通过shapely 的 valid 判断aoi图形是否有效

测试aoi坐标&#xff1a; 116.527712,39.924304;116.527123,39.924353;116.52707,39.923985;116.527685,39.92397;116.527712,39.924304 如图所示是一个有效的坐标&#xff0c;使用python代码判断是否有效&#xff1a; 代码&#xff1a; from shapely.geometry import Polyg…

我开发了一款只用一个注解就实现分布式锁的工具框架

相信大家在JAVA中知道锁的一个概念。在JAVA中&#xff0c;锁是一种机制&#xff0c;用于控制并发代码的执行。锁用于保护共享资源的访问&#xff0c;确保只有一个线程能够同时访问这些资源。锁可以防止多个线程同时执行对共享资源的修改操作&#xff0c;从而避免数据不一致或竞…

探讨在大数据体系中API的通信机制与工作原理

** 引言 关联阅读博客文章&#xff1a;深入解析大数据体系中的ETL工作原理及常见组件 关联阅读博客文章&#xff1a;深入理解HDFS工作原理&#xff1a;大数据存储和容错性机制解析 ** 在当今数字化时代&#xff0c;数据已经成为企业发展和决策的核心。随着数据规模的不断增长…

zabbix_yum安装

目录 一.配置zabbix的yum源 二.安装zabbix server 三.安装zabbix agent 四.安装zabbix web界面 五.安装数据库 六.配置数据库 七.为zabbix server配置数据库 八.启动服务,web界面安装 九.遇到php版本过低问题 前置条件:基于Rocky Linux8操作系统配置的&#xff0c;建议…

Oracle19c ADG搭建

文章目录 一、环境配置1、主机环境2、host文件配置 二、主库配置1、 开启归档2、redo日志3、修改参数文件4、配置TNS文件5、静态监听6、拷贝密码文件 三、备库配置1、开启归档2、redo日志3、修改参数文件4、配置TNS文件5、配置静态监听 四、构建DG1、验证监听2、主库登入rman&a…

【计算机考研】408全年保姆级规划+资料分享

408的复习顺序其实没有标准&#xff0c;推荐先复习数据结构 复习完数据结构之后&#xff0c;再去学操作系统和计算机网络的一些知识点就会很好理解。 数据结构➡计算机组成原理➡操作系统➡计算机网络。 大家可以按照上面这个顺序来学&#xff0c;其实按照这个顺序来学也是因…

泛零售行业大会员经营的发展趋势?

​随着消费者需求的快速变化和技术的不断进步&#xff0c;泛零售行业大会员经营将呈现如下发展趋势: 第一&#xff0c;会员精细化运营和个性服务将上升为泛零售企业未来的战略重点之一。 存量时代&#xff0c;市场竞争加剧&#xff0c;对绝大多数泛零售企业来说&#xff0c;得…

2024三掌柜赠书活动第二十期:搜索之道:信息素养与终身学习的新引擎

目录 目录 前言 信息素养 终身学习 搜索引擎 信息素养与终身学习 关于《搜索之道&#xff1a;信息素养与终身学习的新引擎》 编辑推荐 内容简介 作者简介 图书目录 书中前言/序言 《搜索之道&#xff1a;信息素养与终身学习的新引擎》全书速览 结束语 前言 随着互…

密码算法概论

基本概念 什么是密码学&#xff1f; 简单来说&#xff0c;密码学就是研究编制密码和破译密码的技术科学 例题&#xff1a; 密码学的三个阶段 古代到1949年&#xff1a;具有艺术性的科学1949到1975年&#xff1a;IBM制定了加密标准DES1976至今&#xff1a;1976年开创了公钥密…

微服务之分布式事务概念

微服务之分布式事务概念 CAP定理和Base理论 CAP定理 CAP定理在1998年被加州大学的计算机科学家 Eric Brewer 提出&#xff0c;分布式系统有三个指标&#xff1a; 一致性&#xff08;Consistency&#xff09;可用性&#xff08;Availability&#xff09;分区容错性&#xff…

LLM应用:Prompt flow vs LangChain

背景 Prompt flow和LangChain都是LLM时代&#xff0c;为高效地构建LLM应用而生。 Prompt flow是Microsoft开源的&#xff0c;其诞生时&#xff0c;LangChain已经很有名气了。 所以作为后生的Prompt flow会为我们带来哪些新的东西呢&#xff1f; ​​​​​​​ Prompt flo…

一文了解JAVA的常用API

目录 常用kpimathSystemRuntimeObjectObjectsBigIntegerBigDecima正则表达式包装类 常用kpi 学习目的&#xff1a; 了解类名和类的作用养成查阅api文档的习惯 math 工具类。因为是工具类&#xff0c;因此直接通过类名.方法名(形参)即可直接调用 abs&#xff1a;获取参数绝对…

Docker容器与Serverless的融合:探索《2023腾讯云容器和函数计算技术实践精选集》中的云原生创新案例

Docker容器与Serverless的融合&#xff1a;探索《2023腾讯云容器和函数计算技术实践精选集》中的云原生创新案例 文章目录 Docker容器与Serverless的融合&#xff1a;探索《2023腾讯云容器和函数计算技术实践精选集》中的云原生创新案例一、引言二、《2023腾讯云容器和函数计算…

recover 的使用

一旦mayPanic触发了panic&#xff0c;控制流会跳到defer函数中&#xff0c;尝试执行recover。 如果recover捕获到了panic&#xff0c;它会阻止panic继续传播&#xff0c;程序控制流会继续在safeCall函数的defer函数之后进行。 然而&#xff0c;由于panic导致的提前返回&#xf…

Linux---多线程(下)

前情提要&#xff1a;Linux---多线程(上) 七、互斥 临界资源&#xff1a;多线程执行流共享的资源就叫做临界资源临界区&#xff1a;每个线程内部&#xff0c;访问临界资源的代码&#xff0c;就叫做临界区互斥&#xff1a;任何时刻&#xff0c;互斥保证有且只有一个执行流进入临…

SuccessFactors-cpi-SAP 错误重复机制

系统做复杂的模型不是全量传输&#xff0c;最复杂的是增量模型&#xff0c;增量模型的设计完善&#xff0c;程序的复杂度几何倍增长&#xff0c;今天就讨论下SuccessFactor与HCM集成的增量原理。 首先我们看看同步步骤&#xff0c;见下图 同步过程中有多次数据交互&#xff0c;…

时序预测 | Python实现VMD-CNN-LSTM时间序列预测

时序预测 | Python实现VMD-CNN-LSTM时间序列预测 目录 时序预测 | Python实现VMD-CNN-LSTM时间序列预测预测效果基本介绍模型描述代码设计预测效果 基本介绍 VMD-CNN-LSTM 是一种混合深度学习模型,结合了变分模态分解(VMD)、卷积神经网络(CNN)和长短期记忆网络(LSTM)的…

探索创新前沿,ATFX出席CriptoSummit峰会,共商数字资产市场生态构建

发现、连接并转变您的数字金融愿景。3月20日&#xff0c;以数字资产生态构建和多元化配置为主题的CriptoSummit峰会在智利首都圣地亚哥盛大召开。大会汇聚了智利和拉丁美洲的领导人、学术专家和数字资产爱好者&#xff0c;历时8小时的深度对话与交流&#xff0c;不仅吸引了500余…