【Linux】线程池(第十八篇)

目录

线程池的概念

线程池的基本组成

实现方式

1. 定义任务

2. 创建线程池

3. 初始化和销毁线程池

4. 添加任务

注意事项


线程池的概念

线程池(Thread Pool)是一种基于池化技术设计用于管理线程的资源池。它预先创建并维护多个线程,这些线程等待执行新的任务。当有新任务到来时,线程池会分配一个空闲的线程来执行该任务,而不是为每个任务都创建一个新的线程。这样做的好处包括减少线程的创建和销毁的开销(线程创建和销毁是昂贵的操作),提高资源利用率,以及更好地控制并发执行的线程数量,避免过多的线程导致系统资源耗尽。

线程池的基本概念包括:

  1. 核心线程数(Core Threads):线程池中始终保持活跃的线程数量。即使这些线程是空闲的,它们也不会被销毁,而是等待新的任务到来。

  2. 最大线程数(Maximum Threads):线程池中允许的最大线程数量。当任务队列满了,且已运行的线程数小于最大线程数时,线程池会创建新的线程来执行任务。

  3. 任务队列(Work Queue):用于存放待执行的任务。当所有核心线程都在忙时,新来的任务会被添加到任务队列中等待。队列的实现可以是阻塞队列,也可以是其他类型的队列。

  4. 线程工厂(Thread Factory):用于创建新线程的工厂,允许自定义线程的创建过程,比如设置线程的名称、优先级、守护状态等。

  5. 拒绝策略(Rejected Execution Handler):当任务队列已满,且线程池中的线程数量已达到最大线程数时,新来的任务无法被立即执行。此时,需要有一种策略来处理这些任务,比如直接抛出异常、放弃任务、尝试将任务放入一个等待队列中(这个队列与任务队列不同,它用于存放那些因为线程池容量限制而被拒绝的任务),或者由调用者所在的线程来执行这个任务。

  6. 生命周期管理:线程池需要能够管理自身的生命周期,包括启动、运行和关闭。在关闭过程中,线程池需要等待所有已提交的任务完成(或者等待一定的时间后强制终止未完成的任务),并释放所有占用的资源。

线程池的基本组成

一个基本的线程池通常包含以下几个部分:

  1. 线程池管理器:管理线程池,包括创建和销毁线程、任务分配等。
  2. 工作线程:线程池中真正执行任务的线程。
  3. 任务队列:用于存放待处理的任务。
  4. 任务接口:每个任务需要实现的接口,以便工作线程可以调用执行任务。

实现方式

在 Linux 下,有多种方式可以实现线程池,比如使用 POSIX 线程(pthread)库。下面提供一个简化的基于 pthread 的线程池实现思路:

1. 定义任务

首先,定义一个任务结构体和任务执行函数。

typedef struct task { 
void (*func)(void *arg); 
void *arg; 
struct task *next; 
} task_t; void task_execute(void *arg) { 
task_t *task = (task_t *)arg; 
task->func(task->arg); 
free(task); 
}

2. 创建线程池

实现一个线程池管理器,管理线程和任务队列。

#include <pthread.h> #include <stdlib.h> typedef struct { pthread_mutex_t lock; pthread_cond_t cond; pthread_t *threads; int num_threads; task_t *head; task_t *tail; int shutdown; } threadpool_t; void *thread_function(void *arg) { threadpool_t *pool = (threadpool_t *)arg; while (1) { pthread_mutex_lock(&pool->lock); // 等待任务 while (pool->head == NULL && !pool->shutdown) { pthread_cond_wait(&pool->cond, &pool->lock); } // 检查是否停止 if (pool->shutdown && pool->head == NULL) { pthread_mutex_unlock(&pool->lock); break; } // 取出任务 task_t *task = pool->head; pool->head = task->next; if (pool->head == NULL) { pool->tail = NULL; } pthread_mutex_unlock(&pool->lock); // 执行任务 if (task != NULL) { task_execute(task); } } return NULL; } // 初始化线程池... // 添加任务到线程池... // 销毁线程池...
3. 初始化和销毁线程池

初始化线程池时,你需要创建多个线程,并初始化互斥锁和条件变量。销毁时,需要设置关闭标志,并唤醒所有等待的线程,等待它们退出。

4. 添加任务

添加任务到线程池时,需要加锁保护任务队列,然后将任务添加到队列末尾,并唤醒一个等待的线程(如果有的话)。

注意事项

  • 同步和互斥:线程池中的任务添加、任务执行等操作需要同步和互斥机制来确保数据的一致性和线程安全。
  • 任务队列:任务队列可以基于链表、队列或其他数据结构实现,具体取决于任务类型和执行方式。
  • 错误处理:在实际应用中,需要考虑各种错误情况,如线程创建失败、任务执行出错等。

通过以上步骤,你可以实现一个基本的线程池来管理和执行并发任务。当然,实际应用中可能还需要考虑更多的细节和性能优化。

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

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

相关文章

【例题】lanqiao4425 咖啡馆订单系统

样例输入 3 2 2 1 3 1 2样例输出 3 2样例说明 输入的数组为&#xff1a;【3&#xff0c;1&#xff0c;2】 增量序列为&#xff1a;【2&#xff0c;1】 当增量 h2&#xff1a;对于每一个索引 i&#xff0c;我们会将数组元素 arr[i] 与 arr[i−h] 进行比较&#xff0c;并进行可…

电线电缆制造5G智能工厂物联数字孪生平台,推进制造业数字化转型

电线电缆制造行业作为关键的基础设施建设领域&#xff0c;正积极拥抱新技术&#xff0c;推动生产方式的深刻变革。电线电缆制造5G智能工厂物联数字孪生平台的兴起&#xff0c;不仅为行业注入了新的活力&#xff0c;更为制造业的数字化转型树立了新的标杆。 电线电缆制造5G智能…

es由一个集群迁移到另外一个集群es的数据迁移

迁移es的数据 改下index的索引 就可以了。 查询 用curl -u就可以查询了

Thymeleaf 的创建

pox.xml 文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM…

智能除螨仪——NV040D-SOP8语音芯片方案引领除螨仪新时代

随着物联网技术的快速发展&#xff0c;除螨仪作为家庭清洁的重要工具&#xff0c;其智能化、人性化的设计成为提升市场竞争力的关键。置入语音芯片的除螨仪&#xff0c;通过开机提示、工作状态反馈、操作指引、故障提醒等内容。用户可以更加直观地了解除螨仪的工作状态&#xf…

推荐系统-电商直播 多目标排序算法探秘

前言&#xff1a; 电商直播已经成为电商平台流量的主要入口&#xff0c;今天我们一起探讨推荐算法在直播中所面临的核心问题和解决方案。以下内容参考阿里1688的技术方案整理完成。 一、核心问题介绍 在电商网站中&#xff0c;用户的主要行为是在商品上的行为&#xff0c;直播…

深度学习:(五)初识神经网络

&#xff08;一&#xff09;神经网络的层数 除去输入层&#xff0c;但包括输出层&#xff0c;每一层都有自己的参数。 输入层称为第零层。 &#xff08;二&#xff09;最简单的神经网络&#xff08;逻辑回归&#xff09; 下图中的小圆圈&#xff0c;代表了一种运算。且一个小…

阿里开源多模态大模型Ovis1.6,重塑出海电商AI格局

阿里开源Ovis1.6&#xff1a;多模态领域再夺第一 阿里再一次证明了自己在多模态领域的实力。这一次&#xff0c;阿里国际AI团队开源的多模态大模型Ovis1.6&#xff0c;不仅成功开源&#xff0c;还在多模态评测基准OpenCompass上击败了Qwen2VL-7B、InternVL2-26B和MiniCPM-V-2.…

Docker 进入容器并运行命令的方法

目录 理解 Docker 容器的基本概念 使用 docker exec 进入运行中的容器 基本用法 常用选项解析 选项详解 实际案例演示 1. 进入容器的交互式 Shell 2. 在容器中运行单个命令 3. 以指定用户运行命令 4. 设置环境变量并运行命令 5. 指定工作目录 使用 docker attach 附…

标准库标头 <bit>(C++20)学习

<bit>头文件是数值库的一部分。定义用于访问、操作和处理各个位和位序列的函数。例如&#xff0c;有函数可以旋转位、查找连续集或已清除位的数量、查看某个数是否为 2 的整数幂、查找表示数字的最小位数等。 类型 endian (C20) 指示标量类型的端序 (枚举) 函数 bit_ca…

使用LangGPT提示词让大模型比较浮点数

使用LangGPT提示词让大模型比较浮点数 背景介绍环境准备创建虚拟环境安装一些必要的库安装其他依赖部署大模型启动图形交互服务设置提示词与测试 LangGPT结构化提示词 背景介绍 LLM在对比浮点数字时表现不佳&#xff0c;经验证&#xff0c;internlm2-chat-1.8b (internlm2-cha…

HObject复制耗时试用

测试源码一 //第一步const int N 1000;HObject[] imgs new HObject[N];for (int i 0; i < N; i){HOperatorSet.GenImageConst(out imgs[i], "byte", 1024 i, 1024 i);}//第二步List<HObject> lists new List<HObject>();for(int i 0; i < …

基于PHP的新闻管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于phpMySQL的新闻管理系统。…

MySQL的缓存策略

目录 一、MySQL 缓存方案用来干什么 二、提升MySQL访问性能的方式 1、读写分离&#xff08;MySQL的主从复制&#xff09; 2、连接池 3、异步连接 三、缓存方案是怎么解决的 1、缓存与MySQL一致性状态分析 2、制定热点数据的读写策略 四、缓存方案问题的解决方法 1、缓…

酸枣病虫害智能化防控系统的探索与实践,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建枣类作物种植场景下酸枣病虫害智能检测识别系统

智慧农业&#xff0c;作为现代农业的高级形态&#xff0c;通过集成物联网、大数据、人工智能等先进技术&#xff0c;实现了农业生产过程的精准化、智能化管理。在酸枣等经济作物的种植过程中&#xff0c;病虫害的及时监测与防控直接关系到作物的产量与质量&#xff0c;进而影响…

react hooks--React.memo

基本语法 React.memo 高阶组件的使用场景说明&#xff1a; React 组件更新机制&#xff1a;只要父组件状态更新&#xff0c;子组件就会无条件的一起更新。 子组件 props 变化时更新过程&#xff1a;组件代码执行 -> JSX Diff&#xff08;配合虚拟 DOM&#xff09;-> 渲…

Knife4j 一款基于Swagger的开源文档管理工具

一、简单介绍 1.1 简介 Knife4j 是一款基于Swagger的开源文档管理工具&#xff0c;主要用于生成和管理 API 文档 二、使用步骤&#xff1a; 2.1 添加依赖&#xff1a; <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spr…

spark之不同序列化对比

一&#xff0c;spark的rdd的序列话不同介绍 下面是使用不同序列化后的占用资源和数据大小 2&#xff0c;sparksql中序列化的区别 sparksql中使用序列化和不使用差别不大&#xff0c;英文sparksql中默认使用了encode自己实现的序列化方法&#xff0c;加上与不加序列化差别不大…

编译成功!QT/6.7.2/Creator编译Windows64 MySQL驱动(MSVC版)

相邻你找了很多博文&#xff0c;都没有办法。现在终于找到了正宗。 参考 GitHub - thecodemonkey86/qt_mysql_driver: Typical symptom: QMYSQL driver not loaded. Solution: get pre-built Qt SQL driver plug-in required to establish a connection to MySQL / MariaDB u…

.whl文件下载及pip安装

以安装torch_sparse库为例 一、找到自己需要的版本&#xff0c;点击下载。 去GitHub的pyg-team主页中找到pytorch-geometric包。网址如下&#xff1a; pyg-team/pytorch_geometric​github.com/pyg-team/pytorch_geometric 然后点击如图中Additional Libraries位置的here&am…