图像任务中的并发处理:线程池、Ray、Celery 和 asyncio 的比较
在图像缺陷检测任务中,处理大量图像和点云数据时,高效的并发处理是关键。本文将介绍五种流行的并发处理方法:线程池(concurrent.futures.ThreadPoolExecutor
)、Ray、Celery、asyncio以及搜狗Workflow,并从原理、优缺点、代码实现等方面进行详细对比,最后探讨它们的相同点和区别以及性能差异。
1. 线程池(concurrent.futures.ThreadPoolExecutor
)
原理
线程池是一种用于并发执行任务的机制,它通过创建一个线程池来管理线程的生命周期,从而避免频繁地创建和销毁线程带来的开销。线程池的工作原理如下:
- 线程池初始化:根据
corePoolSize
初始化核心线程。 - 任务提交:当任务提交到线程池时,根据当前线程数判断:
- 若当前线程数小于
corePoolSize
,创建新的线程执行任务。 - 若当前线程数大于或等于
corePoolSize
,任务被加入workQueue
队列。
- 若当前线程数小于
- 任务处理:当有空闲线程时,从
workQueue
中取出任务执行。 - 线程扩展:若队列已满且当前线程数小于
maximumPoolSize
,创建新的线程处理任务。 - 线程回收:当线程空闲时间超过
keepAliveTime
,多余的线程会被回收,直到线程数不超过corePoolSize
。 - 拒绝策略:若队列已满且当前线程数达到
maximumPoolSize
,则根据拒绝策略处理新任务。
优缺点
- 优点:
- 降低线程创建及销毁带来的资源消耗。
- 避免线程间互抢资源而导致阻塞现象。
- 提高线程的可管理性和稳定性。
- 缺点:
- 占用一定量的内存空间。
- CPU调度开销随着线程数量增加。
- 程序实现的复杂度变高。
代码实现
import concurrent.futures
import cv2
import numpy as npdef detect_defect(image_path):image = cv2.imread(image_path)gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)defect_count = len(contours)return defect_countif __name__ == '__main__':image_paths = ['path/to/image1.jpg', 'path/to/image2.jpg']with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:results = list(executor.map(detect_defect, image_paths))for result in results:print(f'Detected defects: {result}')
2. Ray
原理
Ray
是一个用于构建和运行分布式应用程序的框架,支持Python。它可以用来并行处理多个任务,并且可以扩展到分布式环境。Ray的工作原理如下:
- Ray通过事件总线(EventBus)和事件订阅机制来实现任务的异步处理和状态一致性。
- Ray支持状态(State)、事件(Event)和事件总线(EventBus)的概念,通过这些机制来管理任务的执行和状态变化。
优缺点
- 优点:
- 支持CPU密集型和I/O密集型任务。
- 提供了细粒度的任务调度和资源管理。
- 可以轻松扩展到多个节点,适合大规模数据处理。
- 缺点:
- 使用和配置相对复杂。
- 在单机环境下,可能会引入额外的资源开销。
代码实现
import ray
import cv2
import numpy as npray.init()@ray.remote
def detect_defect(image_path):image = cv2.imread(image_path)gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)defect_count = len(contours)return defect_countif __name__ == '__main__':image_paths = ['path/to/image1.jpg', 'path/to/image2.jpg']results = [detect_defect.remote(path) for path in image_paths]for result in results:print(f'Detected defects: {ray.get(result)}')
3. Celery
原理
Celery
是一个分布式任务队列系统,可以用来异步执行耗时的任务。它通常用于处理大量的任务,并且可以扩展到分布式环境。Celery的工作原理如下:
- Celery使用消息队列(如RabbitMQ或Redis)来分配任务。任务被生产者(Producer)创建并发送到队列中,由消费者(Worker)从队列中取出并执行。
- Celery支持任务的异步执行,允许任务立即执行或者延迟执行。
- Celery提供了灵活的任务调度机制,允许任务的可靠传递和执行。
优缺点
- 优点:
- 支持分布式环境和任务调度。
- 提供了丰富的任务调度和队列管理功能。
- 支持任务的持久化,即使系统崩溃,任务也不会丢失。
- 缺点:
- 配置和使用相对复杂,需要设置消息代理(如RabbitMQ或Redis)。
- 在单机环境下,可能会引入额外的资源开销。
代码实现
from celery import Celery
import cv2
import numpy as npapp = Celery('defect_detection', broker='pyamqp://guest@localhost//')@app.task
def detect_defect(image_path):image = cv2.imread(image_path)gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)defect_count = len(contours)return defect_countif __name__ == '__main__':image_paths = ['path/to/image1.jpg', 'path/to/image2.jpg']results = []for path in image_paths:result = detect_defect.delay(path)results.append(result)for result in results:print(f'Detected defects: {result.get()}')
4. asyncio
原理
asyncio
是Python的异步I/O框架,可以用来处理大量的I/O密集型任务。它通过事件循环来管理异步任务,适合处理高并发的I/O操作。asyncio
的工作原理如下:
asyncio
通过事件循环来管理任务的执行,任务可以被挂起和恢复。asyncio
支持异步函数和协程,允许任务的并发执行。asyncio
提供了丰富的API来处理异步任务,包括任务的创建、等待和取消。
优缺点
- 优点:
- 适合处理大量的I/O密集型任务。
- 轻量级,相比线程池,
asyncio
的开销更小。
- 缺点:
- 不适合CPU密集型任务。
- 使用
asyncio
需要一定的异步编程经验。
代码实现
import asyncio
import cv2
import numpy as npasync def detect_defect(image_path):loop = asyncio.get_running_loop()image = await loop.run_in_executor(None, cv2.imread, image_path)gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)defect_count = len(contours)return defect_countasync def main():image_paths = ['path/to/image1.jpg', 'path/to/image2.jpg']tasks = [detect_defect(path) for path in image_paths]results = await asyncio.gather(*tasks)for result in results:print(f'Detected defects: {result}')if __name__ == '__main__':asyncio.run(main())
5. 搜狗Workflow
原理
搜狗Workflow是一个高性能的异步调度框架,广泛应用于搜狗及搜狐集团的多个团队,用于处理海量在线请求。Workflow的工作原理如下:
- 多维调度队列:Workflow采用多维调度队列的创新数据结构。内部有一个线程池和一个主队列,每个任务属于一个以名字区分的子队列。这种结构确保:
- 有空闲线程时,任务实时调起,不受队列名影响。
- 线程繁忙时,同一队列名下的任务按FIFO顺序执行,队列间平等对待。
- 无论任务提交顺序和计算时间,多个队列可同时完成。
- 任务调度算法:
- 线程从主队列中取出任务执行。
- 执行前,任务从子队列中移除,若子队列还有任务,则将下一个任务放入主队列。
- 提交任务时,按队列名放入子队列,若子队列为空,则任务提交到主队列。
- 任务封装:Workflow封装了调度的基本单位,如网络交互或线程计算任务。每个任务可包含上下文和具体实现接口。
优缺点
- 优点:
- 高性能:Workflow通过高效的调度算法和资源管理,实现高吞吐量和低延迟的异步处理。
- 灵活性:支持多种协议(如HTTP、WebSocket、TCP/IP)和任务类型(如网络请求、计算任务)。
- 可扩展性:支持多维调度队列,可以灵活配置任务的优先级和调度策略。
- 缺点:
- 使用和配置相对复杂,需要一定的C++编程经验。
- 在单机环境下,可能会引入额外的资源开销。
代码实现
#include "workflow/WFHttpServer.h"
#include "workflow/WFGoTask.h"
#include "opencv2/opencv.hpp"class ImageDefectDetectionTask : public WFGoTask {
public:ImageDefectDetectionTask(const std::string& image_path) : WFGoTask("image_defect_detection_queue"), image_path_(image_path) {}void run() override {// 加载图像cv::Mat image = cv::imread(image_path_);if (image.empty()) {std::cerr << "Failed to load image: " << image_path_ << std::endl;return;}// 进行缺陷检测std::vector<cv::Rect> defects = detect_defects(image);// 处理检测结果for (const auto& defect : defects) {cv::rectangle(image, defect, cv::Scalar(0, 0, 255), 2);}// 保存或显示结果cv::imshow("Defects", image);cv::waitKey(0);}private:std::string image_path_;std::vector<cv::Rect> detect_defects(const cv::Mat& image) {// 使用深度学习模型进行缺陷检测// 假设dnn_detect_defects是一个封装好的函数return dnn_detect_defects(image);}
};int main() {// 初始化WorkflowWFTaskFactory::initialize();// 图像文件路径列表std::vector<std::string> image_paths = {"path/to/image1.jpg", "path/to/image2.jpg"};// 创建并启动图像缺陷检测任务std::vector<ImageDefectDetectionTask*> tasks;for (const auto& path : image_paths) {ImageDefectDetectionTask* task = new ImageDefectDetectionTask(path);task->start();tasks.push_back(task);}// 等待所有任务完成for (auto task : tasks) {task->wait();delete task;}return 0;
}
相同点和区别
相同点
- 并发处理:四种方法都可以实现并发处理,提高任务执行效率。
- 异步执行:都支持异步执行任务,避免阻塞主线程。
区别
- 适用场景:
- 线程池:适合处理I/O密集型任务,简单易用,但不适合CPU密集型任务。
- Ray:适合处理CPU密集型和I/O密集型任务,支持分布式环境。
- Celery:适合处理大量的任务,支持分布式环境和任务调度。
- asyncio:适合处理大量的I/O密集型任务,轻量级。
- 搜狗Workflow:适合处理高性能的异步任务,支持多种协议和任务类型。
- 配置复杂度:
- 线程池:配置简单。
- Ray:配置相对复杂。
- Celery:配置和使用相对复杂。
- asyncio:需要一定的异步编程经验。
- 搜狗Workflow:配置和使用相对复杂,需要一定的C++编程经验。
- 资源开销:
- 线程池:资源开销较小。
- Ray:在单机环境下可能会引入额外的资源开销。
- Celery:在单机环境下可能会引入额外的资源开销。
- asyncio:资源开销最小。
- 搜狗Workflow:在单机环境下可能会引入额外的资源开销。
性能差异
- 线程池:在I/O密集型任务中表现良好,但在CPU密集型任务中由于GIL限制,性能受限。
- Ray:在CPU密集型和I/O密集型任务中表现良好,适合分布式环境。
- Celery:在处理大量任务时表现良好,适合分布式环境和任务调度。
- asyncio:在I/O密集型任务中表现最佳,适合高并发场景。
- 搜狗Workflow:在高性能异步任务中表现最佳,适合处理多种协议和任务类型。
总结
根据你的具体需求选择合适的工具。如果你需要处理大量的图像和点云数据,并且希望扩展到分布式环境,Ray
和Celery
可能是更好的选择。如果你只需要在单机环境下处理I/O密集型任务,asyncio
和线程池可能更适合。如果你需要高性能的异步任务处理,并且在 c++环境 ,可以考虑使用搜狗Workflow。
相关文章:
图像任务中的并发处理:线程池、Ray、Celery 和 asyncio 的比较
在图像缺陷检测任务中,处理大量图像和点云数据时,高效的并发处理是关键。本文将介绍五种流行的并发处理方法:线程池(concurrent.futures.ThreadPoolExecutor)、Ray、Celery、asyncio以及搜狗Workflow,并从原…...
DeepSeek 赋能智能物流:解锁仓储机器人调度的无限可能
目录 一、智能物流仓储机器人调度现状1.1 传统调度面临的挑战1.2 现有智能调度的进展与局限 二、DeepSeek 技术探秘2.1 DeepSeek 核心技术原理2.2 DeepSeek 的独特优势 三、DeepSeek 在智能物流仓储机器人调度中的创新应用3.1 智能任务分配与调度3.2 路径规划与避障优化3.3 实时…...
C#上传图片后压缩
上传的图片尺寸不一,手机拍照的有2000*2000像素的,对实际使用来说 文件尺寸太大,文件也有近4M 下面是直接压缩的方法 1、安装包 Magick.NET-Q16-AnyCPU 2、上代码 /// <summary> /// 缩放图片 /// </summary> /// <param …...

uniapp路由跳转toolbar页面
需要阅读uview-ui的API文档 注意需要使用type参数设置后才起作用 另外route跳转的页面会覆盖toolbar工具栏 toConternt(aid) {console.log(aid:, aid)this.$u.route({// url: "pages/yzpg/detail",url: "pages/yzappl/index",// url: "pages/ind…...

【linux】知识梳理
操作系统的分类 1. 桌⾯操作系统: Windows/macOS/Linux 2. 移动端操作系统: Android(安卓)/iOS(苹果) 3. 服务器操作系统: Linux/Windows Server 4. 嵌⼊式操作系统: Android(底层是 Linux) Liunx介绍 liunx系统:服务器端最常见的操作系统类型 发行版:Centos和Ubuntu 远程连接操…...
PostgreSQL 内置扩展列表
PostgreSQL 内置扩展列表 PostgreSQL 自带了许多内置扩展(built-in extensions),这些扩展提供了额外的功能而不需要额外安装。以下是主要的内置扩展分类和说明: 标准内置扩展(随核心安装) 1. 管理类扩展…...

NodeMediaEdge快速上手
NodeMediaEdge快速上手 简介 NodeMediaEdge是一款部署在监控摄像机网络前端中,拉取Onvif或者rtsp/rtmp/http视频流并使用rtmp/kmp推送到公网流媒体服务器的工具。 通过云平台协议注册到NodeMediaServer后,可以同NodeMediaServer结合使用。使用图形化的…...

ChatOn:智能AI聊天助手,开启高效互动新时代
在当今快节奏的生活中,无论是工作、学习还是日常交流,我们常常需要快速获取信息、整理思路并高效完成任务。ChatOn 正是为满足这些需求而生,它基于先进的 ChatGPT 和 GPT-4o 技术,为用户提供市场上最优秀的中文 AI 聊天机器人。这…...

基于Vue3.0的【Vis.js】库基本使用教程(002):图片知识图谱的基本构建和设置
文章目录 3、图片知识图谱3.1 初始化图片知识图谱3.2 修改节点形状3.3 修改节点背景颜色3.4 完整代码下载3、图片知识图谱 3.1 初始化图片知识图谱 1️⃣效果预览: 2️⃣关键代码: 给节点添加image属性: const nodes = ref([{id: 1,...
监督学习 vs 无监督学习:AI两大学习范式深度解析
监督学习 vs 无监督学习:AI两大学习范式深度解析 引言:机器如何"学习"? 想象教孩子识别动物:一种方法是展示图片并告诉名称(监督学习),另一种是让孩子自己观察动物特征并分类&#…...

C# Costura.Fody 排除多个指定dll
按照网上的说在 FodyWeavers.xml 里修改 然后需要注意的是 指定多个排除项 不是加 | 是换行 一个换行 就排除一项 我测试的 <?xml version"1.0" encoding"utf-8"?> <Weavers xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance&quo…...
NodeJS全栈WEB3面试题——P8项目实战类问题(偏全栈)
📦 8.1 请描述你做过的 Web3 项目,具体技术栈和你负责的模块? 我主导开发过一个基于 NFT 的数字纪念平台,用户可以上传照片并生成独特的纪念 NFT,结合 IPFS 和 ERC-721 实现永存上链。 🔧 技术栈…...
小白的进阶之路系列之五----人工智能从初步到精通pytorch张量
张量 张量是一种特殊的数据结构,与数组和矩阵非常相似。在PyTorch中,我们使用张量来编码模型的输入和输出,以及模型的参数。 张量类似于NumPy的ndarray,除了张量可以在gpu或其他硬件加速器上运行。事实上,张量和NumPy数组通常可以共享相同的底层内存,从而消除了复制数据…...

设计模式——迭代器设计模式(行为型)
摘要 本文详细介绍了迭代器设计模式,这是一种行为型设计模式,用于顺序访问集合对象中的元素,同时隐藏集合的内部结构。文章首先定义了迭代器设计模式并阐述了其核心角色,包括迭代器接口、具体迭代器、容器接口和具体容器。接着&a…...

android-studio-2024.3.2.14如何用WIFI连接到手机(给数据线说 拜拜!)
原文:Android不用数据线就能调试真机的方法—给数据线说 拜拜!(adb远程调试) android-studio-2024.3.2.14是最新的版本,如何连接到手机,可用WIFI,可不用数据线,拜拜 第一步…...
[特殊字符] xbatis 一款好用 ORM 框架 1.8.8-M2 发布,节省 1/3 代码和时间的框架!!!
1.8.8-M2 更新内容: 1:优化默认值,对同一类减少重复调用2:优化分页,支持 limit (-1) 进行忽略分页3:优化 UpdateChain.set;支持.set (SysUser::getVersion, c -> c.plus (1))4:优化 @Fetch, 已增强,无法配置 groupby、forceUseIn(已去除)5:增强 @Fetch,支持中间…...

js 动画库、2048核心逻辑、面试题add[1][2][3]+4
1、js 动画库 web animation api (1)初始化代码 hmtl、css 部分 初始化全局背景黑色初始化黄色小球 js 部分 监听全局点击事件创建并添加元素 class"pointer" 的 div 标签 设置 left、top 位置监听动画结束事件,移除该元素 定位小…...

华为OD机试真题——书籍叠放(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
2025 B卷 200分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…...

PyTorch-Transforms的使用(二)
对图像进行处理 安装open cv ctrlP 看用法 ToTensor的使用 常见的Transforms 归一化的图片 两个长度为三的数组,分别表示三个通道的平均值和标准差 Resize() Compose() 合并执行功能,输入进去一个列表&a…...

Pytorch知识点2
Pytorch知识点 1、官方教程2、张量🧱 0、数组概念🧱 1. 创建张量📐 2. 张量形状与维度🔢 3. 张量数据类型➗ 4. 张量的数学与逻辑操作🔄 5. 张量的就地操作📦 6. 复制张量🚀 7. 将张量移动到加速…...
Java详解LeetCode 热题 100(23):LeetCode 206. 反转链表(Reverse Linked List)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 反转前后对比2.2 核心思路 3. 解法一:迭代法(三指针法)3.1 算法思路3.2 详细图解3.3 Java代码实现3.4 代码执行过程演示3.5 执行结果示例3.6 优化版本(简化代码)…...
StarRocks部署方案详解:从单机到分布式集群
#### 一、引言 StarRocks(原名DorisDB)是一款高性能的MPP(大规模并行处理)分析型数据库,支持实时查询、高并发和复杂分析场景。其基于列式存储和向量化执行引擎的设计,使其在大数据OLAP领域表现优异。本文…...

AWS API Gateway 配置WAF(中国区)
问题 需要给AWS API Gateway配置WAF。 AWS WAF设置 打开AWS WAF首页,开始创建和配置WAF,如下图: 设置web acl名称,然后开始添加aws相关资源,如下图: 选择资源类型,但是,我这里出…...

【前端面经】百度一面
写在前面:面经只是记录博主遇到的题目。每题的答案在编写文档的时候已经有问过deepseek,它只是一种比较普世的答案,要学得深入还是靠自己 Q: <html><style>.a {background-color: red;width: 200px;height: 100px;}…...
嵌入式学习笔记 - freeRTOS 动态创建任务跟静态创建任务的区别,以及内存回收问题
FreeRTOS动态创建任务和静态创建任务各有优缺点,选择哪种方式取决于具体的应用场景和需求。 一 动态创建任务 优点: 灵活性高:动态任务在运行时通过pvPortMalloc()动态分配内存,系统自动管理栈和任务控制块…...

[免费]微信小程序网上花店系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序网上花店系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序网上花店系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
如何给老旧 iOS App 添加安全保护?用 Ipa Guard 对 IPA 文件混淆加固实录
在大多数安全讨论中,我们习惯关注新项目的安全性,从代码结构、API 设计、用户认证机制出发,构建完善的防护体系。但现实是,很多开发者都在维护一些年久失修的老项目——技术架构老旧、团队成员流失、源码混乱甚至缺失。 我最近接…...
C#语音录制:使用NAudio库实现语音录制功能详解
C#语音录制:使用NAudio库实现语音录制功能详解 在音频处理领域,C# 凭借其强大的生态系统和丰富的类库,为开发者提供了便捷的开发工具。NAudio 库就是其中一款用于音频处理的优秀开源库,它支持多种音频格式和音频设备操作。今天&a…...
[蓝桥杯]缩位求和
缩位求和 题目描述 在电子计算机普及以前,人们经常用一个粗略的方法来验算四则运算是否正确。 比如:248153720248153720 把乘数和被乘数分别逐位求和,如果是多位数再逐位求和,直到是 1 位数,得 24814>14524814…...
MySQ-8.42 MGR 组复制部署及详解
目录 1 MGR要求 2 操作系统信息和软件版本 3 集群架构图 4 MySQL MGR 主库部署步骤 1 MGR要求 InnoDB 存储引擎 表上必须存在主键或唯一非空索引 MGR可允许的最大节点9个 2 操作系统信息和软件版本 rootu24-mysql-mgr-42:~# cat /etc/issue Ubuntu 24.04.2 LTS \n \l mysql…...