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

Python - 协程基本使用详解【demo】

一. 前言

协程(Coroutine)是一种轻量级的线程,也被称为用户级线程或绿色线程。它是一种用户态的上下文切换方式,比内核态的线程切换更为轻量级,能够高效的支持大量并发操作。

2. 使用协程的好处

Python 中的协程是通过 asyncio 模块实现的,使用协程可以带来以下好处:

  1. 轻量级并发操作:协程的运行过程中不需要进行线程切换和上下文切换,避免了这些操作的开销,因此比传统的线程更加轻量级,可以支持更多并发操作。
  2. 提高程序性能:协程避免了线程上下文切换的开销,可以大大提高程序的执行效率。并且在 Python 中,协程的调度是由事件循环(Event
    Loop)来完成的,事件循环采用的是单线程方式,能够充分利用 CPU 资源,进一步提高了程序的性能。
  3. 简化异步编程:协程使得异步编程更加简单,在编写异步程序时可以避免回调地狱(Callback
    Hell)的问题,提高程序的可读性和可维护性。而且通过 Python 的 async/await
    语法,可以使用同步的方式编写异步代码,使得代码更加易于理解和调试。
  4. 更加灵活的控制流程:协程可以方便地进行挂起和恢复操作,因此可以很灵活地控制流程。例如可以在协程中使用条件判断、循环等语句,进行更加复杂的流程控制操作。

总之,协程是一种高效、轻量级的并发编程方式,能够提高程序的性能,简化异步编程,使得控制流程更加灵活,是 Python 中重要的并发编程工具之一。

三. 代码示例

1. 基本使用

import asyncioasync def task1():await asyncio.sleep(1)print('Task 1 done')async def task2():await asyncio.sleep(2)print('Task 2 done')async def main():print('Starting tasks')# 并发执行 task1 和 task2 任务await asyncio.gather(task1(), task2())print('All tasks done')asyncio.run(main())

运行结果
在这里插入图片描述

2. 进阶使用:异步任务循环任务

方法一:

import asyncio
import randomasync def producer(queue):while True:value = random.randint(0, 10)print(f"Produced: {value}")await queue.put(value)await asyncio.sleep(random.random())async def consumer(queue):while True:value = await queue.get()print(f"Consumed: {value}")await asyncio.sleep(random.random())async def main():queue = asyncio.Queue()task_producer = asyncio.create_task(producer(queue))task_consumer = asyncio.create_task(consumer(queue))await asyncio.gather(task_producer, task_consumer)asyncio.run(main())

在上面的代码中,我们定义了一个 producer 函数和一个 consumer 函数,它们都接受一个 asyncio.Queue 对象作为输入,并在其中实现协程的逻辑。其中 producer 函数会在队列中不断生成随机数,并将其放入队列中;consumer 函数则会不断从队列中取出随机数并进行消费。

在 main 函数中,我们首先创建了一个 asyncio.Queue 对象用于协程之间的通信,然后使用 asyncio.create_task 函数创建了两个任务,分别是生产者任务和消费者任务。最后,我们使用 asyncio.gather 函数来运行这两个任务,当其中任何一个任务完成时,main 函数也会结束。

需要注意的是,当我们使用协程时,需要使用 await 关键字来挂起协程的执行,等待其他协程的执行或者等待 I/O 操作完成。同时,在协程中不应该使用阻塞式的操作,比如 time.sleep(),而应该使用异步 I/O 操作,比如 asyncio.sleep()

方法二

import asyncio
import randomasync def producer(queue):while True:value = random.randint(0, 10)print(f"Produced: {value}")await queue.put(value)await asyncio.sleep(random.random())async def consumer(queue):while True:value = await queue.get()print(f"Consumed: {value}")await asyncio.sleep(random.random())async def main():queue = asyncio.Queue()'''方法一'''# task_producer = asyncio.create_task(producer(queue))# task_consumer = asyncio.create_task(consumer(queue))# await asyncio.gather(task_producer, task_consumer)'''方法二'''await asyncio.wait([producer(queue), consumer(queue)])asyncio.run(main())

以上协程的两种启动方式的的区别在于它们等待任务完成的方式不同。

await asyncio.gather(task_producer, task_consumer) 会并发地运行多个任务,并等待它们全部完成后才会返回结果。也就是说,这种方式只有在所有任务都执行完成后,才会进入下一步。

await asyncio.wait([producer(queue), consumer(queue)]) 则是将多个协程对象(通过列表进行传递)传递给 asyncio.wait() 函数,这个函数也会等待多个协程同时完成。不同的是,asyncio.wait() 函数会返回两个集合(即 done 和 pending),done 集合包含已经完成的任务,pending 集合包含还未完成的任务。因此可以通过遍历 done 集合取得协程的结果。

总的来说,asyncio.gather() 更加简单易用,适合并发执行多个任务并等待它们全部完成的情况。而 asyncio.wait() 则更加灵活,并且可以实时获取任务的执行结果。

3. 启动方式差异

注意,在 Python 3.7 以前,我们需要使用 asyncio.get_event_loop().run_until_complete() 函数来运行协程任务。但在 Python 3.7 及以后的版本中,我们可以使用更为简洁的 asyncio.run() 函数来运行协程任务。
示例代码如下:

import asyncio
import randomasync def producer(queue):while True:value = random.randint(0, 10)print(f"Produced: {value}")await queue.put(value)await asyncio.sleep(random.random())async def consumer(queue):while True:value = await queue.get()print(f"Consumed: {value}")await asyncio.sleep(random.random())async def main():queue = asyncio.Queue()'''方法一'''# task_producer = asyncio.create_task(producer(queue))# task_consumer = asyncio.create_task(consumer(queue))# await asyncio.gather(task_producer, task_consumer)'''方法二'''await asyncio.wait([producer(queue), consumer(queue)])'''协程启动的方式一'''
# asyncio.run(main())'''协程启动的方式二'''
new_loop = asyncio.new_event_loop()
asyncio.set_event_loop(new_loop)
new_loop.run_until_complete(main())

总之,协程是一种高效、轻量级的并发编程方式,能够提高程序的性能,简化异步编程,使得控制流程更加灵活,是 Python 中重要的并发编程工具之一。

以上就是关于Python - 协程基本使用的介绍,希望对你有所帮助,谢谢!

相关文章:

Python - 协程基本使用详解【demo】

一. 前言 协程(Coroutine)是一种轻量级的线程,也被称为用户级线程或绿色线程。它是一种用户态的上下文切换方式,比内核态的线程切换更为轻量级,能够高效的支持大量并发操作。 2. 使用协程的好处 Python 中的协程是通…...

Android MVVM架构模式,详详详细学习

MVVM(Model-View-ViewModel) 是一种基于数据绑定的架构模式,用于设计和组织应用程序的代码结构。它将应用程序分为三个主要部分:Model(模型)、View(视图)和ViewModel(视…...

亿赛通电子文档安全管理系统 RCE漏洞复现

0x01 产品简介 亿赛通电子文档安全管理系统(简称:CDG)是一款电子文档安全加密软件,该系统利用驱动层透明加密技术,通过对电子文档的加密保护,防止内部员工泄密和外部人员非法窃取企业核心重要数据资产&…...

星际争霸之小霸王之小蜜蜂(三)--重构模块

目录 前言 一、为什么要重构模块 二、创建game_functions 三、创建update_screen() 四、修改alien_invasion模块 五、课后思考 总结 前言 前两天我们已经成功创建了窗口,并将小蜜蜂放在窗口的最下方中间位置,本来以为今天将学习控制小蜜蜂,结…...

JS的解析与Js2Py使用

JS的解析与Js2Py使用 JS的解析事件监听器搜索关键字请求关联JS文件 Js2PyJs2Py的简单使用安装Js2Py执行JavaScript代码调用JavaScript函数 Js2Py的应用示例创建JavaScript文件使用JavaScript JS的解析 在一个网站中,登录密码通常是会进行加密操作的,那么…...

Spring Bean的生命周期总结(包含面试题)

目录 一、Bean的初始化过程 1. 加载Spring Bean 2. 解析Bean的定义 3. Bean属性定义 4. BeanFactoryPostProcessor 扩展接口 5. 实例化Bean对象 6. Aware感知 7. 初始化方法 8. 后置处理 9. destroy 销毁 二、Bean的单例与多例模式 2.1 单例模式(Sin…...

SpringjDBCTemplate_spring25

1、首先导入两个包,里面有模板 2、transtion事务 jDbc操作对象,底层默认的是事务: 3、我们java一般对实体类进行操作。 4、第一步写好坐标。 创建一个Account表 数据修改用update 数据进去了...

设计模式——桥接模式

引用 桥我们大家都熟悉,顾名思义就是用来将河的两岸联系起来的。而此处的桥是用来将两个独立的结构联系起来,而这两个被联系起来的结构可以独立的变化,所有其他的理解只要建立在这个层面上就会比较容易。 基本介绍 桥接模式(Br…...

改进YOLO系列:2.添加ShuffleAttention注意力机制

添加ShuffleAttention注意力机制 1. ShuffleAttention注意力机制论文2. ShuffleAttention注意力机制原理3. ShuffleAttention注意力机制的配置3.1common.py配置3.2yolo.py配置3.3yaml文件配置1. ShuffleAttention注意力机制论文 论文题目:SA-NET: SHUFFLE ATTENTION …...

利用Opencv实现人像迁移

前言: Hello大家好,我是Dream。 今天来学习一下如何使用Opencv实现人像迁移,欢迎大家一起参与探讨交流~ 本文目录: 一、实验要求二、实验环境三、实验原理及操作1.照片准备2.图像增强3.实现美颜功能4.背景虚化5.图像二值化处理6.人…...

Lnton羚通算法算力云平台在环境配置时 OpenCV 无法显示图像是什么原因?

问题&#xff1a; cv2.imshow 显示图像时报错&#xff0c;无法显示图像 0%| | 0/1 [00:00<…...

【JavaEE进阶】MyBatis的创建及使用

文章目录 一. MyBatis简介二. MyBatis 使用1. 数据库和数据表的创建2. 创建Mybatis项目2.1 添加MyBatis框架支持2.2 设置MyBatis配置信息 3. MyBatis开发流程4. MyBatis查询数据库测试 三. MyBatis 流程1. MyBatis 查询数据库流程2. MyBatis 框架交互流程图 一. MyBatis简介 M…...

职业学院物联网实训室建设方案

一、概述 1.1专业背景 物联网&#xff08;Internet of Things&#xff09;被称为继计算机、互联网之后世界信息产业第三次浪潮&#xff0c;它并非一个全新的技术领域&#xff0c;而是现代信息技术发展到一定阶段后出现的一种聚合性应用与技术提升&#xff0c;是随着传感网、通…...

3 个 ChatGPT 插件您需要立即下载3 ChatGPT Extensions You need to Download Immediately

在16世纪&#xff0c;西班牙探险家皮萨罗带领约200名西班牙士兵和37匹马进入了印加帝国。尽管印加帝国的军队数量达到了数万&#xff0c;其中包括5,000名精锐步兵和3,000名弓箭手&#xff0c;他们装备有大刀、长矛和弓箭等传统武器。但皮萨罗的军队中有100名火枪手&#xff0c;…...

屏蔽socket 实例化时,握手阶段报错信息WebSocket connection to ‘***‘ failed

事情起因是这样的&#xff1a; 我们网站是需要socket链接实行实时推送服务&#xff0c;有恶意竞争对手通过抓包或者断网&#xff0c;获取到了我们的socket链接地址&#xff0c;那么他就可以通过java写一个脚本无限链接这个socket地址。形成dos攻击。使socket服务器资源耗尽&…...

单发多框检测(SSD)【动手学深度学习】

单发多框检测模型主要由一个基础网络块和若干多尺度特征块串联而成。基本网络用于从输入图像中提取特征,可以使用深度卷积神经网络,原论文中选用了在分类层之前阶段的VGG,现在也常用ResNet替代。 我们可以设计基础网络,使它输出的高和宽较大,这样基于该特征图生成的锚框数…...

“RFID与光伏板的完美融合:探索能源科技的新时代!“

随着科技的不断发展&#xff0c;人类创造出了许多令人惊叹的发明。其中&#xff0c;RFID&#xff08;Radio Frequency Identification&#xff09;技术的应用在各个领域日益广泛。最近的研究表明&#xff0c;将RFID技术应用于光伏板领域&#xff0c;不仅可以提高光伏板的效率&a…...

算法leetcode|71. 简化路径(rust重拳出击)

文章目录 71. 简化路径&#xff1a;样例 1&#xff1a;样例 2&#xff1a;样例 3&#xff1a;样例 4&#xff1a;提示&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 71. 简化路径&#xff1a;…...

网络技术Vlan技术STP(第一课)

一 Vlan技术的学习 对命令的增删改查 #### 1&#xff09;创建vlan[SW1]vlan 2 [2-4094] 创建vlan[SW1]vlan batch 10 20 30 创建多个不连续的vlan[SW1]display vlan 查看vlan信息[SW1]vlan batch 50 to 60创建多个连续的vlan[SW1]vlan2[SW1-vlan2]description caiwu添加描述信…...

SpringBoo t+ Vue 微人事 (十一)

职位修改操作 在对话框里面做编辑的操作 添加对话框 <el-dialogtitle"修改职位":visible.sync"dialogVisible"width"30%"><div><el-tag>职位名称</el-tag><el-input size"small" class"updatePosIn…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...