协程/线程/进程的简单应用

使用FastApi模拟网络IO接口

import timefrom fastapi import FastAPIapp = FastAPI()#  文件名 api.py
#  运行: uvicorn api:app --reload@app.get("/sleep/{times}")
def sleep(times: int):# 模拟接口耗时time.sleep(times)return {"sleep": times}

asyncio协程

协程: 使用 async def 语法定义的函数总是为协程函数,即使它们不包含 awaitasync 关键字。

引自: 8. 复合语句 — Python 3.12.3 文档

对比 并发运行 的效率

# _*_ coding : UTF-8 _*_
# @Time : 2024/4/22 下午7:12
# @Auther : Tiam
# @File : 异步
# @Project : play-python
# @Desc :import asyncio
import threading
import timeimport aiohttpdef get_run_time(func):"""获取 async函数运行时间:param func::return:"""async def wrapper(*args, **kwargs):start_time = time.time()await func(*args, **kwargs)end_time = time.time()print(f"函数 {func.__name__} 运行时间: {end_time - start_time} 秒")return wrapperasync def req(second):print(threading.current_thread().name, second)url = f'http://127.0.0.1:8000/sleep/{second}'async with aiohttp.ClientSession() as session:async with session.get(url) as response:print("Status:", response.status)return url, response.statuscounts = 5@get_run_time
async def main():for i in range(counts):await req(i)# [await req(i) for i in range(counts)]  # 等同于以上操作@get_run_time
async def main_gather():# https://docs.python.org/zh-cn/3/library/asyncio-task.html#asyncio.gather  # 新版本推荐使用 asyncio.TaskGroupresult = await asyncio.gather(*[req(i) for i in range(counts)])print(result)@get_run_time
async def main_task_group():# https://docs.python.org/zh-cn/3/library/asyncio-task.html#asyncio.TaskGroupasync with asyncio.TaskGroup() as tg:#  重点: create_task 会将 协程(用async修饰的函数) 转换成 一个可并行调度的任务task-object# https://docs.python.org/zh-cn/3/library/asyncio-task.html#task-objecttasks = [tg.create_task(req(i)) for i in range(counts)]for task in tasks:print(task.result())if __name__ == '__main__':# 同步顺序执行, 耗时  0+1+2+3+4 = 10# asyncio.run(main())  # 函数 main 运行时间: 10.017327308654785 秒# 并发运行, 只耗时最长的一个IO# asyncio.run(main_gather())  # 函数 main_gather 运行时间: 4.008605718612671 秒# 3.11 +asyncio.run(main_task_group())  # 函数 main_task_group 运行时间: 4.16048264503479 秒

Process进程/Thread线程

import time
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutorimport requestsdef get_run_time(func):def wrapper(*args, **kwargs):start_time = time.time()func(*args, **kwargs)end_time = time.time()print(f"函数 {func.__name__} 运行时间: {end_time - start_time} 秒")return wrapperdef req():with requests.session() as session:with session.get('http://localhost:8000/sleep/1') as response:print("Status:", response.status_code)counts = 5@get_run_time
def main1():with ThreadPoolExecutor(max_workers=counts) as executor:for i in range(counts):executor.submit(req)@get_run_time
def main2():req()@get_run_time
def main3():with ProcessPoolExecutor(max_workers=counts) as executor:for i in range(counts):executor.submit(req)if __name__ == '__main__':main1()  # 函数 main1 运行时间: 3.0591320991516113 秒main2()  # 函数 main1 运行时间: 3.0591320991516113 秒main3()  # 函数 main3 运行时间: 4.668190956115723 秒, 多进程增加了 进程切换开销 时间

总结:

多进程和多线程是两种常见的并发执行方式,它们各自有不同的特点和适用场景:

多进程(Multi-Process)

优点

  1. 隔离性:每个进程都有独立的内存空间和系统资源,一个进程的崩溃不会直接影响到其他进程。
  2. 资源利用:可以更好地利用多核CPU,通过创建多个进程来执行CPU密集型任务。
  3. 简化编程:编程相对容易,通常不需要考虑锁和同步资源的问题。
  4. 容错性:进程间相互独立,具有更强的容错性。

缺点

  1. 资源消耗:进程的创建和销毁需要较多的系统资源和时间。
  2. 通信开销:进程间通信(IPC)机制比线程间通信复杂,可能会影响性能。
  3. 上下文切换:进程间的上下文切换开销较大。

多线程(Multi-Threading)

优点

  1. 资源共享:同一进程下的线程共享进程的内存和资源,数据共享和通信更容易。
  2. 执行开销:线程的创建和销毁比进程更快,资源消耗较小。
  3. 上下文切换:线程间的上下文切换比进程间快,因为它们共享相同的地址空间。
  4. 响应性:适合需要快速响应的应用程序,如用户界面程序。

缺点

  1. 同步问题:线程之间需要同步和互斥机制来避免竞态条件和数据冲突。
  2. GIL限制:在某些语言(如Python)中,全局解释器锁(GIL)限制了线程的并行执行。
  3. 稳定性风险:一个线程的不稳定可能影响整个进程的稳定性。

选择多进程还是多线程?

  • CPU密集型任务:如果任务主要是计算密集型的,并且需要充分利用多核CPU,多进程可能是更好的选择。
  • IO密集型任务:对于IO密集型任务,多线程可能更合适,因为线程可以在等待IO操作时被操作系统挂起,让出CPU给其他线程使用。
  • 并发数要求:需要处理大量并发请求时,多线程可以更高效地利用资源。
  • 安全性和稳定性:如果程序需要高安全性和稳定性,多进程提供的隔离性可能更合适。
  • 开发和维护难度:如果程序逻辑较为简单,或者开发者对并发编程不够熟悉,多进程可能更容易开发和维护。

在实际应用中,两种模型也可以结合使用,例如,可以使用多进程模型来处理多个并行的任务,而每个进程内部使用多线程来进一步提高并发度。

关系:

每个进程可以有多个线程, 每个线程下又可以存在多个协程

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

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

相关文章

rc_visard 3D Stereo Senso

1 简介 rc_visard 3D立体视觉传感器 支持的接口标准 GenICam Generic Interface for CamerasGigE Gigabit Ethernet 词汇表 SGM semi-global matching 半全局匹配 SLAM Simultaneous Localization and Mapping 即时定位与地图构建 2 安全 3 硬件规格 坐标系 rc_visar…

TypeScript 中 interface 和 type 的使用#记录

一、interface:接口 interface A{label: string; }const aa ((aObj: A) > {console.log(aObj.label);//123return aObj.label; })aa({label: 123}) 1、可选属性 interface A{label: string;age?: number; } 2、只读属性 interface A{label: string;age?:…

231 基于matlab的北斗信号数据解析

基于matlab的北斗信号数据解析,多通道和单通道接收到的北斗信号数据,利用接收到的北斗数据(.dat .txt文件),进行解析,得到初始伪距,平滑伪距,载波相位,并计算其标准差&am…

翱途开发平台新手上路-体验APP移动手机办公

O2OA(翱途)开发平台拥有配套的移动办公APP,支持IOS和安卓端,用户可在连接O2云之后,使用APP使用移动办公。移动办公APP开放源代码,不会产生任何费用。本篇主要简单讲述初如何完成服务器连接O2云,实现移动办公。 一、先决…

Barnes-Hut t-SNE:大规模数据的高效降维算法

在数据科学和分析中,理解高维数据集中的底层模式是至关重要的。t-SNE已成为高维数据可视化的有力工具。它通过将数据投射到一个较低维度的空间,提供了对数据结构的详细洞察。但是随着数据集的增长,标准的t-SNE算法在计算有些困难,…

什么是IoT?

什么是IoT? IoT,即物联网(Internet of Things),是通过信息传感设备和互联网将各种物品连接起来,实现智能化的识别、定位、跟踪、监控和管理的网络系统。 以下是关于IOT的一些详细解释: 基本概…

JVM之本地方法栈和程序计数器和堆

本地方法栈 本地方法栈是为虚拟机执行本地方法时提供服务的 JNI:Java Native Interface,通过使用 Java 本地接口程序,可以确保代码在不同的平台上方便移植 不需要进行 GC,与虚拟机栈类似,也是线程私有的,…

OCP Java17 SE Developers 复习题13

答案 D, F. There is no such class within the Java API called ParallelStream, so options A and E are incorrect. The method defined in the Stream class to create a parallel stream from an existing stream is parallel(); therefore, option F is correct, and o…

高斯溅射融合之路(一)- webgl渲染3d gaussian splatting

大家好,我是山海鲸的技术负责人。之前已经写了一个GIS融合系列。其实CesiumJS的整合有相当的难度,同时也有很多方面的工作,很难在几篇文章内写完,整个山海鲸团队也是投入了接近两年的时间,才把周边整套工具链进行了完善…

Linux中inode号与日志分析

一.inode号 1.inode表结构 元信息:每个文件的属性信息,比如:文件的大小,时间,类型,权限等,称为文件的元数据(meta data 元信息 ) 元数据是存放在inode(index node)表中…

Spring Kafka—— KafkaListenerEndpointRegistry 隐式注册分析

由于我想在项目中实现基于 Spring kafka 动态连接 Kafka 服务,指定监听 Topic 并控制消费程序的启动和停止这样一个功能,所以就大概的了解了一下 Spring Kafka 的几个重要的类的概念,内容如下: ConsumerFactory 作用:…

Opencv_2_ 图像色彩空间转换

ColorInvert.h 内容如下&#xff1a; #pragma once #include <opencv.hpp> using namespace std; #include <opencv.hpp> using namespace cv; using namespace std; class ColorInvert{ public : void colorSpaceInvert(Mat&image); }; ColorInvert.cpp…

高效过滤器检漏方法选择指南及关键注意事项一览

在生物制药企业中&#xff0c;高效过滤器&#xff08;HEPA&#xff09;的检漏工作是确保洁净室能够达到并保持设计的洁净级别的关键步骤。这关系到产品的质量和安全&#xff0c;因此必须遵循相关法规标准和操作流程。 关于北京中邦兴业 北京中邦兴业科技有限公司是一家国家高新…

element中file-upload组件的提示‘按delete键可删除’,怎么去掉?

问题描述 element中file-upload组件会出现这种提示‘按delete键可删除’ 解决方案&#xff1a; 这是因为使用file-upload组件时自带的提示会盖住上传的文件名&#xff0c;修改一下自带的样式即可 ::v-deep .el-upload-list__item.is-success.focusing .el-icon-close-tip {d…

基于SpringBoot的宠物领养网站管理系统

基于SpringBootVue的宠物领养网站管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 宠物领养 宠物救助站 宠物论坛 登录界面 管理员界面 摘要 基于Spr…

1.C++入门

目录 1.C关键字 2.命名空间 作用域方面的优化 a.命名空间定义 b.命名空间使用 3.C 输入&输出 1.C关键字 C有63个关键字&#xff0c;C语言有32个关键字&#xff0c;存在重叠如荧光笔标出 2.命名空间 作用域方面的优化 如果变量&#xff0c;函数和类的名称都存在于全…

AI自动生成PPT文档 aippt的API介绍文档

官方链接直达&#xff01; 产品介绍​ 能力介绍​ AiPPT 是一款智能生成演示幻灯片的在线工具。专业设计团队打造海量模板资源&#xff0c;输入标题即可轻松生成完整的PPT。同时 AiPPT 支持导入多格式文档一键生成 PPT&#xff0c;让 PPT 创作更加高效。聚焦于内容&#xff0…

安装zabbix server

目录 1、实验环境 2、yum 安装zabbix server 2.1 解决权限问题和放行流量 2.2 安装zabbix-server 1、实验环境 操作系统rhel8zabbix6.0TLS数据库mysql8.0.30IP地址192.168.81.131时间配置NTP时间服务器同步 2、yum 安装zabbix server 如果通过yum源安装&#xff0c;操作系…

SysetmUI开机是否显示Keyguard的流程

KeyguardViewMediator的onSystemReady方法 没有启用keyguard时KeyguardViewMediator的log&#xff1a; onSystemReady 方法 doKeyguardLocked LockPatternUtils.isLockScreenDisabled 来判断是否启用 public final static String DISABLE_LOCKSCREEN_KEY "lockscreen.…

信息化工作人员必备常识4——ping命令详解【不间断发包自定义发包的大小自定义发包次数】

信息化工作人员必备常识4——ping命令详解【不间断发包&自定义发包的大小&自定义发包次数】 前言回顾pingtelnetnslookup命令 ping 命令详解帮助手册不间断向目标 IP 发送数据包 -t定义发送数据包的大小 -l-t&-l 验证网络承载能力自定义发送数据包的次数统计响应时…