手把手教你写Linux线程池

news/2024/5/20 3:09:19/文章来源:https://blog.csdn.net/tgdzsjh/article/details/128135753

手把手教你写Linux线程池

如果需要线程池源码,关注Linux兵工厂,并由大量Linux资料赠送。

线程池

顾名思义,存储线程的池子。线程池是线程的一种使用模式。在平常业务开发中常规的逻辑是遇到任务然后创建线程去执行。但是线程的频繁创建就类似于内存的频繁申请和销毁,会给操作系统带来大的压力,进而影响整体的性能。所以我们一次申请好一定数量而定线程,然后将线程的管理操作交给线程池,就避免了在短时间内不断创建与销毁线程的代价,线程池不但能够保证内核的充分利用,还能防止过分调度,并根据实际业务情况进行修改。

使用线程池的好处

  • 任务到来后立马就有线程去执行任务,节省了创建线程的时间
  • 防止服务器线程过多导致的系统过载问题
  • 相对于进程池,线程池资源占用较少,但是健壮性很差
  • 降低资源消耗,通过重用已经创建的线程来降低线程创建和销毁的消耗
  • 提高线程的可管理性,线程池可以统一管理、分配、调优和监控其中的线程

什么情况下使用线程池

  • 需要大量的线程来完成任务,且完成任务的时间比较短
  • 对性能要求苛刻的应用
  • 接收突发性的大量请求,但不至于使服务器因此产生大量线程的应用

线程不是越多越好

线程的越多,可能会导致线程切换越频繁, 进而还有可能导致程序运行效率降低。多线程程序的运行效率, 是一个正态分布的结果, 线程数量从1开始增加, 随着线程数量的增加, 程序的运行效率逐渐变高, 直到线程数量达到一个临界值, 再次增加线程数量时, 程序的运行效率会减小(主要是由于频繁的线程切换影响线程运行效率)。

  • 线程若不限制数量的创建,线程创建过多,资源耗尽,有程序崩溃的风险
  • 处理一个短时间任务时,线程会频繁创建和销毁,占用系统资源,降低系统性能

Linux如何实现一个线程池

  • 每个任务在放入任务队列时设置好需要处理的数据和处理函数
  • 线程池中的线程负责从任务队列当中获取任务,并进行处理
    在这里插入图片描述

代码实现过程

  • 创建一个任务类CTask,可以设置处理任务的回调func以及需要处理的数据m_data
  • 创建一个线程池类CThreadPool,成员变量有设置线程池中线程的最大数量thr_max,任务缓冲队列m_queue,互斥量m_mutex,用于实现对缓冲队列的安全性,条件变量m_cond,用于实现线程池中线程的同步

创建任务类

/* 任务类 */
class CTask
{
public:CTask(){}~CTask(){}void SetTask(int data, func handler) // 设置数据和处理接口{m_data = data;m_handler = handler;}void Do() // 执行任务{return m_handler(m_data);}private:int  m_data;     // 数据func m_handler;  // 处理接口
};

创建线程池类

    1. 创建线程池
    /* 创建线程池 */for (int i = 0; i < m_SumMax; i++){pthread_t tid;int ret = pthread_create(&tid, NULL, ThrPoolRun, this);if (ret != 0){printf("thread create error\n");}}
    1. 任务放入队列
    bool TaskPush(CTask &task){pthread_mutex_lock(&m_Mutex);m_Queue.push(task);pthread_mutex_unlock(&m_Mutex);pthread_cond_signal(&m_Mond);return true;}
    1. 线程池空闲线程从队列获取任务并处理
    CThreadPool *p = (CThreadPool*)arg;while (p->m_bIsRun){pthread_mutex_lock(&p->m_Mutex);/* 等待任务到来 */while (p->m_Queue.empty()){pthread_cond_wait(&p->m_Mond, &p->m_Mutex);}/* 取出任务 */CTask Task;Task =p->m_Queue.front();p->m_Queue.pop();pthread_mutex_unlock(&p->m_Mutex);/* 处理任务 */Task.Do();}

main函数

void TaskFunc1(int nData)
{printf("TaskFunc1, ThreadId: %p, nData:%d\n", pthread_self(), nData);sleep(1);
}void TaskFunc2(int nData)
{printf("TaskFunc2, ThreadId: %p, nData:%d\n", pthread_self(), nData);sleep(1);
}int main(int argc, char const *argv[])
{CThreadPool ThreadPool;for (size_t i = 0; i < 10; i++){CTask Task;(0 == (i % 2)) ? Task.SetTask(i, TaskFunc1) : Task.SetTask(i, TaskFunc2);ThreadPool.TaskPush(Task);  // 放入任务队列}sleep(3);return 0;
}

运行结果

  • 10个任务被5个线程分别处理完
    1

总结

至此,一个简单的线程池实例就完成了。实际工作中我们可以根据实际的业务量来初始化线程池中线程的个数,并根据任务量的多少动态的增加或减少线程池中的线程。好了,现在让我们行动起来吧,自己编写一个线程池。

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

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

相关文章

Java Tomcat内存马——Listener内存马

目录 &#xff08;一&#xff09;前置知识 0x01 什么是Listener 0x02 Listener的简单案例 0x03 Listener流程分析 &#xff08;二&#xff09;注入分析 (三&#xff09;实现内存马 得到完整的内存马 (四&#xff09;漏洞复现 其他的payload: 总结 &#xff08;一&#…

Java+JSP+MySQL基于SSM的雷锋车队管理系统的设计与实现-计算机毕业设计

项目介绍 随着我国国民经济的发展和人文素质的不断提高&#xff0c;越来越多的爱心人士出现在了社会的各种角落之中&#xff0c;其中的哥和爱心人士&#xff0c;组织了一种基于交通和车辆之间的互助的民间组织&#xff0c;这种组织叫做雷锋爱心车队&#xff0c;而且雷锋爱心车…

什么牌子蓝牙耳机通话质量好?通话质量好的蓝牙耳机推荐

蓝牙耳机作为手机的最佳伴侣&#xff0c;已经成为老百姓日常生活必备。每次有大品牌发布新款蓝牙耳机&#xff0c;几乎都能够得到很好的反响&#xff0c;蓝牙耳机不仅在音质上有了很大的提升&#xff0c;并且在其他功能也在不断的提升&#xff0c;使用蓝牙耳机通话避免不了电话…

商务部研究院信用所、启信宝联合发布《中国商务信用发展指数报告(2022)》

近期&#xff0c;商务部国际贸易经济合作研究院信用研究所与合合信息全资子公司上海生腾数据科技有限公司&#xff08;简称“生腾数据”&#xff09;联合发布了《中国商务信用发展指数报告&#xff08;2022&#xff09;》&#xff08;简称《报告》&#xff09;。为准确反映中国…

glxy_阿里云存储

阿里云OSS储存 讲师的添加实现&#xff1a;oss服务 访问并登陆阿里云&#xff0c;&#xff0c;实名认证 产品分类---->对象储存OSS 开通OSS 进入管理控制台 使用OSS前先创建bucket java 代码实现 准备工作&#xff1a;创建操作阿里云oss许可证&#xff08;阿里云颁发…

得一微冲刺科创板上市:拟募资约12亿元,2021年营收同比增长260%

撰稿|汤汤 来源|贝多财经 近日&#xff0c;得一微电子股份有限公司&#xff08;下称“得一微”&#xff09;在上海证券交易所科创板递交招股书&#xff08;申报稿&#xff09;。本次冲刺科创板上市&#xff0c;得一微拟公开发行不超过2354万股股份&#xff0c;计划募资12.24亿…

zookeeper学习(一)zk特性与节点数据类型详解(2022)

Zookeeper是一个开源的分布式协调框架&#xff0c;主要用来解决分布式集群中应用系统的一致性问题。从设计模式角度来理解其实zk是一个基于观察者模式设计的分布式服务管理框架。 CAP理论&#xff1a; cap理论指出对于一个分布式计算系统来说&#xff0c;不可能同时满足以下三…

golang知识点整理

目录 1、goroutine GMP模型 2、goroutine阻塞的处理 3、goroutine内存泄漏 4、map原理、扩容 5、go内存管理 6、go的gc 1、goroutine GMP模型 1. G代表一个goroutine对象&#xff0c;每次go调用的时候&#xff0c;都会创建一个G对象 2. M代表一个线程&#xff0c;每次创建…

SpringCloud:Gateway之限流、熔断

目录 一、服务雪崩简介及压测实践演示 ​编辑 二、sentinel简单模式之流控QPS案例 什么是Sentinel ​ 安装Sentinel控制台 三、sentinel流控简单模式之并发线程数案例 四、sentinel流控之关联模式&链路模式 关联模式 链路模式 五、sentinel降级之平均响应时间&…

最新 | VDA-ISA5.0.4最新版本发布,汽车企业如何增强信息安全?

汽车行业拥有广泛而复杂的供应链&#xff0c;包括汽车整车制造商、不同层级的零部件厂商、供应商、服务商等众多企业。在这个链条上&#xff0c;其中任何一家企业的网络安全问题不论是数据泄密还是内外部攻击都有可能对整个供应链造成巨大影响。 比如2021年6月&#xff0c;某德…

能力提高篇--协调能力【对接】

作为一名安防技术支持工程师&#xff0c;正常情况下我们的日常主要为解决问题&#xff0c;然而对于重大项目或者复杂项目&#xff0c;更多的情况下我们的职责为收集客户需求&#xff0c;拉通研发侧评估&#xff0c;确认需求&#xff0c;确认程序交付时间&#xff0c;测试和最终…

【python与数据分析】实验十三 北京市空气质量

目录 一、实验内容 二、完成情况 三、数据分析 1.问题描述 2.编程思路 3.程序代码 4.程序运行结果 &#xff08;1&#xff09;2014年-2019年AQI时间序列折线图 &#xff08;2&#xff09;各年AQI折线图、AQI直方图、PM2.5与AQI散点图、空气质量整体情况的饼图 ​&am…

10-18-hive-元数据及其他方式与hive交互

10-hive-元数据及其他方式访问hive&#xff1a; 使用元数据服务的方式访问 Hive (类似将hive提供了一个服务端) 1&#xff09;在hive-site.xml 文件中添加如下配置信息 <!-- 指定存储元数据要连接的地址 --> <property> <name>hive.metastore.uris</nam…

[附源码]计算机毕业设计SpringBoot网上鲜花购物系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Day16-购物车页面-商品列表修改购物车商品的勾选状态

提纲挈领&#xff1a; 我的操作&#xff1a; 1》当用户点击 radio 组件&#xff0c;希望修改当前商品的勾选状态&#xff0c;此时用户可以为 my-goods 组件绑定 radio-change 事件&#xff0c;从而获取当前商品的 goods_id 和 goods_state&#xff1a; 定义 radioChangeHandle…

leetcode-每日一题-1779-找到最近的有相同 X 或 Y 坐标的点(简单,数学思想)

今天这道每日一题很简单&#xff0c;没啥可说的&#xff0c;细心点即可 1779. 找到最近的有相同 X 或 Y 坐标的点 难度简单73收藏分享切换为英文接收动态反馈 给你两个整数 x 和 y &#xff0c;表示你在一个笛卡尔坐标系下的 (x, y) 处。同时&#xff0c;在同一个坐标系下给你一…

GEE开发之Modis_GPP数据分析和获取

GEE开发之Modis_GPP数据分析和获取1.GPP2.MOD系列和MYD系列区别3.MOD17A2H(500m/8天)4.MYD17A2H(500m/8天)4.1 MYD17A2H下的指数4.2 遥感影像查看5.GPP日数据下载(以MYD17A2H为例)6.GPP月数据下载(以MYD17A2H为例)7.GPP年数据下载(以MYD17A2H为例)前言&#xff1a;主要介绍利用…

flask入门教程之数据库保存

计算机操作数据时&#xff0c;一般是在内存中对数据进行处理&#xff0c;但是计算机的内存空间有限&#xff0c;服务器操作大量数据时&#xff0c;容易造成内存不足&#xff0c;且一旦计算机关机&#xff0c;则内存数据就丢失。所以我们需要将数据进行存储。 持久化&#xff0…

Java 基础数据类型占用内存空间和字符串编码简介(二)

Java 基础数据类型占用内存空间简介一 计算机简介1.基本概念2.CPU 三级缓存3.本机参数查看二 数据占用内存情况1.多线程Demo2.结果解析1.直接计算2.volatile 计算3.缓存行填充一 计算机简介 结合多线程计算机的硬件&#xff0c;从侧面理解数据存储如何影响我们的程序 1.基本概…

门面/外观模式

一、门面模式 1、定义 门面模式&#xff08;Facade Pattern&#xff09;又称作外观模式&#xff0c;是指提供一个统一的接口&#xff0c;用来访问子系统中的一群接口&#xff0c;属于结构型设计模式。 门面模式的主要特征是定义了一个高层接口&#xff0c;让子系统更容易使用。…