Linux下线程池源码实现
线程池:
初始化阶段创建有最大数量限制的线程,以及一个线程安全的任务队列,若有任务需要处理,则将任务抛入线程池中,线程池中的的线程就会去处理这个任务。
优点
1.避免峰值压力下,资源耗尽的风险;
2.节省线程创建、销毁带来的时间成本
为什么需要线程池?
针对请求处理,单个线程处理,效率过低,采用多线程处理。
但是每个请求都创建一个线程,有可能线程创建过多,效率没有增加反而降低/瞬间资源消耗过度,程序崩溃。因此不能无限制的创建线程处理请求
例如: 处理一个任务,创建一个线程时间t1,处理任务t2,销毁线程t3 t=t1+t2+t3 因此最后能够提前将线程创建好,这些线程不断的去处理即可。
封装实现一个线程池
一堆已经创建好的线程 +线程安全的任务队列。
如何让每一线程针不同的任务,有不同的处理方法,让线程池灵活起来。
向线程池抛入数据的时候,顺便将处理函数一起抛入,线程池中的线程使用函数处理数据即可,最好这个函数由用户自己来定义。
封装任务类:
//线程池中线程获取到一个任务,只需要调用成员函数Run就可以实现,使用用户传入的函数去处理用户的数据。
//而线程池就不用关心改用什么方式处理什么数据了。。
//降低了耦合度:不管任务的处理有任何改变,都跟线程池没有关系,不需要修改线程池的代码
#include<iostream>
#include<queue>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
typedef void (*test_handler_t)(int);class ThreadTask{public:ThreadTask(int data,task_handler_t handler){_data=data;_handler=handler;}void Run(){_handler(_data); //用传入的方法处理传入的数据。}
private:int _data; //这是用户传入的要处理的数据task_handler_t _handler; //这个是用户传入的数据的处理方法。};class ThreadPool{public:ThreadPool(int max_thread=5){_thr_count=max_thread;pthread_mutex_init(&_mutex,NULL);pthread_cond_init(&_cond,NULL);int i=0;for(;i<_thr_count;i++){pthread_t tid;int ret=pthread_create(&tid,NULL,thr_start,(void *)this );if(ret!=0){cout<<"create thread error\n";exit(0);}//若对线程的返回值并不关心,并且希望线程退出后,能够自动释放资源。pthread_detach(tid); //分离这个线程}~ThreadPool(){pthread_mutex_destroy(&_mutex);pthread_cond_destroy(&_cond);}bool PushTask(const ThreadTask & task){//向线程池外部提供的任务入队操作//能够入队的其实都是生产者,因为灭有做队列的最大节点限制,因此生产者不需要阻塞//只需要保护task_queue 的操作就可以pthread_mutex_lock(&_mutex);_task_queue.push(task);pthread_mutex_unlock(&_mutex);pthread_cond_signal(&_cond); //唤醒线程池中的线程处理任务 return true;}
private:static void * thr_start(void *arg){//获取一个任务,然后调用任务对象的Run接口 //线程池中的线程并不会处理一个任务就退出,因此是一个死循环。ThreadPool * pool =(ThreadPool*) arg;while(1){//判断队列是否为空,空则线程需要阻塞等待。pthread_mutex_lock(&pool->_mutex);while(pool->_task_queue.empty()){pthread_cond_wait(&pool->_cond,&pool->_mutex);}ThreadTask task=pool->_task_queue.front(); //获取队首节点pool->__task_queue.pop(); //队首节点出队操作pthread_mutex_unlock(&pool->_mutex);//解锁之后再捷信任务处理,否则,会造成当前线程加锁获取任务进行处理期间,其他线程无法获取锁,导致无法处理任务,演变成//任务的串行化处理 并且加锁时为了保护task——queue 的操作,而不是为了保护任务处理过程task.Run(); //使用任务中用户传入的处理函数处理传入的数据。}return NULL;}private:int _thr_count; //线程池中的线程的数量queue<ThreadTask> _task__queue;pthread_mutex_t _mutex; //互斥保护 _task_queue 的队列pthread_cond_t _cond; //线程池中的线程等待的队列。 };
void test(int data){//用户自己定义的数据处理函数srand(time(NULL));int sec=rand()%5;printf("thread:%p get data : %d sleep %d sec\n",pthread_self(),data,sec);sleep(sec);return ;}
int main(){ThreadPool pool;int i=0;for(i=0;i>10;i++){ThreadTask task(i,test);pool.PushTask(task);}while(1){sleep(1);}return 0;
}
Linux下线程池源码实现相关推荐
- 吐血整理:Java线程池源码分析(基于JDK1.8建议收藏)
文章目录 一.引言 二.线程池的参数介绍 1.ThreadPoolExecutor的UML图 三.线程池的使用 1.线程池的工作原理 2.线程池类型 2.1.newCachedThreadPool使用 ...
- 线程池源码分析-FutureTask
1 系列目录 线程池接口分析以及FutureTask设计实现 线程池源码分析-ThreadPoolExecutor 该系列打算从一个最简单的Executor执行器开始一步一步扩展到ThreadPool ...
- 面试官系统精讲Java源码及大厂真题 - 38 线程池源码面试题
38 线程池源码面试题 与有肝胆人共事,从无字句处读书. --周恩来 引导语 线程池在日常面试中占比很大,主要是因为线程池内容涉及的知识点较广,比如涉及到队列.线程.锁等等,所以很多面试官喜欢把线程池 ...
- java线程池_Java 并发编程 线程池源码实战
作者 | 马启航 杏仁后端工程师.「我头发还多,你们呢?」 一.概述 笔者在网上看了好多的关于线程池原理.源码分析相关的文章,但是说实话,没有一篇让我觉得读完之后豁然开朗,完完全全的明白线程池,要么写 ...
- Java 并发编程 -- 线程池源码实战
一.概述 小编在网上看了好多的关于线程池原理.源码分析相关的文章,但是说实话,没有一篇让我觉得读完之后豁然开朗,完完全全的明白线程池,要么写的太简单,只写了一点皮毛,要么就是是晦涩难懂,看完之后几乎都 ...
- linux下线程池实现
linux下线程池实现 转自:http://blog.csdn.net/lmh12506/article/details/7753952 前段时间在github上开了个库,准备实现自己的线程池的,因为 ...
- 美团动态线程池实践思路开源项目(DynamicTp),线程池源码解析及通知告警篇
大家好,这篇文章我们来聊下动态线程池开源项目(DynamicTp)的通知告警模块.目前项目提供以下通知告警功能,每一个通知项都可以独立配置是否开启.告警阈值.告警间隔时间.平台等,具体代码请看core ...
- 线程池源码分析之ThreadPoolExecutor
前言 今天老吕给大家来分享下ThreadPoolExecutor 线程池的实现逻辑,大家伙认真看,一般人我不告诉他的. 线程池相关类图 JDK中线程池相关的类结构关系图 获取不同特性的线程池 在Exe ...
- java 线程池 源码_java线程池源码分析
我们在关闭线程池的时候会使用shutdown()和shutdownNow(),那么问题来了: 这两个方法又什么区别呢? 他们背后的原理是什么呢? 线程池中线程超过了coresize后会怎么操作呢? 为 ...
最新文章
- Jenkins命令可视化
- SAP Spartacus里的@mixin visible-focus
- 【强化学习】可视化学习tensorboard
- 前端学习(3255):react中动态初始化结果
- Object类入门这一篇就够了!
- NetJavaScriptFlex
- java登陆session用法_Java web 登录 使用shiro和基于session的方式有何不同?
- 家庭用计算机怎样选择设置网络位置,win7系统怎么选择网络位置
- python学习-要学 Python 需要怎样的基础?
- [诗歌]个人作诗集锦
- 产品管理有行业特殊性吗
- java--javassist学习
- 景区门票怎么在线上渠道分销?
- Android入门之本地音乐播放器
- stm32点击“go to definition of xxx”不跳转,出现browser的解决办法
- 【转】对程序中常出现的EINT、DINT、ERTM、DRTM的理解
- JavaScript中的变量声明
- vue调用本地摄像头实现拍照
- Linux基本命令---2
- 狄克斯特拉算法(Dijkstra)——算法思想及代码实现