线程池:

初始化阶段创建有最大数量限制的线程,以及一个线程安全的任务队列,若有任务需要处理,则将任务抛入线程池中,线程池中的的线程就会去处理这个任务。
优点
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下线程池源码实现相关推荐

  1. 吐血整理:Java线程池源码分析(基于JDK1.8建议收藏)

    文章目录 一.引言 二.线程池的参数介绍 1.ThreadPoolExecutor的UML图 三.线程池的使用 1.线程池的工作原理 2.线程池类型 2.1.newCachedThreadPool使用 ...

  2. 线程池源码分析-FutureTask

    1 系列目录 线程池接口分析以及FutureTask设计实现 线程池源码分析-ThreadPoolExecutor 该系列打算从一个最简单的Executor执行器开始一步一步扩展到ThreadPool ...

  3. 面试官系统精讲Java源码及大厂真题 - 38 线程池源码面试题

    38 线程池源码面试题 与有肝胆人共事,从无字句处读书. --周恩来 引导语 线程池在日常面试中占比很大,主要是因为线程池内容涉及的知识点较广,比如涉及到队列.线程.锁等等,所以很多面试官喜欢把线程池 ...

  4. java线程池_Java 并发编程 线程池源码实战

    作者 | 马启航 杏仁后端工程师.「我头发还多,你们呢?」 一.概述 笔者在网上看了好多的关于线程池原理.源码分析相关的文章,但是说实话,没有一篇让我觉得读完之后豁然开朗,完完全全的明白线程池,要么写 ...

  5. Java 并发编程 -- 线程池源码实战

    一.概述 小编在网上看了好多的关于线程池原理.源码分析相关的文章,但是说实话,没有一篇让我觉得读完之后豁然开朗,完完全全的明白线程池,要么写的太简单,只写了一点皮毛,要么就是是晦涩难懂,看完之后几乎都 ...

  6. linux下线程池实现

    linux下线程池实现 转自:http://blog.csdn.net/lmh12506/article/details/7753952 前段时间在github上开了个库,准备实现自己的线程池的,因为 ...

  7. 美团动态线程池实践思路开源项目(DynamicTp),线程池源码解析及通知告警篇

    大家好,这篇文章我们来聊下动态线程池开源项目(DynamicTp)的通知告警模块.目前项目提供以下通知告警功能,每一个通知项都可以独立配置是否开启.告警阈值.告警间隔时间.平台等,具体代码请看core ...

  8. 线程池源码分析之ThreadPoolExecutor

    前言 今天老吕给大家来分享下ThreadPoolExecutor 线程池的实现逻辑,大家伙认真看,一般人我不告诉他的. 线程池相关类图 JDK中线程池相关的类结构关系图 获取不同特性的线程池 在Exe ...

  9. java 线程池 源码_java线程池源码分析

    我们在关闭线程池的时候会使用shutdown()和shutdownNow(),那么问题来了: 这两个方法又什么区别呢? 他们背后的原理是什么呢? 线程池中线程超过了coresize后会怎么操作呢? 为 ...

最新文章

  1. Jenkins命令可视化
  2. SAP Spartacus里的@mixin visible-focus
  3. 【强化学习】可视化学习tensorboard
  4. 前端学习(3255):react中动态初始化结果
  5. Object类入门这一篇就够了!
  6. NetJavaScriptFlex
  7. java登陆session用法_Java web 登录 使用shiro和基于session的方式有何不同?
  8. 家庭用计算机怎样选择设置网络位置,win7系统怎么选择网络位置
  9. python学习-要学 Python 需要怎样的基础?
  10. [诗歌]个人作诗集锦
  11. 产品管理有行业特殊性吗
  12. java--javassist学习
  13. 景区门票怎么在线上渠道分销?
  14. Android入门之本地音乐播放器
  15. stm32点击“go to definition of xxx”不跳转,出现browser的解决办法
  16. 【转】对程序中常出现的EINT、DINT、ERTM、DRTM的理解
  17. JavaScript中的变量声明
  18. vue调用本地摄像头实现拍照
  19. Linux基本命令---2
  20. 狄克斯特拉算法(Dijkstra)——算法思想及代码实现

热门文章

  1. 左声道,右声道和立体声
  2. STlink无法下载?解决过程记录。
  3. 东北大学计算机学院杨金柱院长,电子信息学院赴东北大学走访、调研
  4. 如何在所有流媒体服务中搜索电影或电视节目
  5. matlab植物叶面积,植物叶面积测量方法综述
  6. 【AI绘画】绝美春天插画,人人都是插画师
  7. 《全球互联网金融商业模式:格局与发展》——第2章,第4节众筹型券商
  8. 企业技术中心申报条件
  9. puppy linux u盘 分区,让安装在U盘上的Puppy Linux像安装在硬盘上一样工作
  10. JAVA生成阿里云直播推流和拉流