线程池概念:一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。

应用场景:1、需要大量的线程来完成任务,且完成任务的时间比较短;2、对性能要求苛刻的应用;3、接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用
不使用线程池的情况:若是一个数据请求的到来伴随一个线程去创建,就会产生一定的风险以及一些不必要的消耗。
1、线程若不限制数量的创建,在峰值压力下,线程创建过多,资源耗尽,有程序崩溃的风险;
2、处理一个短时间任务时,会有大量的资源用于线程的创建与销毁成本上。
功能:线程池是使用了已经创建好的线程进行循环处理任务,避免了大量线程的频繁创建与销毁的时间成本

如何实现一个线程池

线程池 = 大量线程 + 任务缓冲队列

困难与解决方案:在创建线程时,都是伴随创建线程的入口函数,一旦创建就无法改变,导致线程池进行任务处理的方式过于单一,灵活性太差。若任务队列中的任务,不仅仅是单纯的数据,而是包含处理任务方法在内的数据,这时候,线程池的线程是一条普通的执行流,只需要使用传入的方法去处理数据即可。这样子就可以提高线程池的灵活性

代码实现流程:定义一个任务类Task,成员变量有要处理的数据_data和处理数据的方法_handler。成员函数有设置要处理数据和处理方式的函数setTask,还有一个处开始处理数据的函数run(创建线程时传入的方法,由于创建线程必须有入口函数,这里用run封装所有的处理方式,让所有线程都将run置为入口函数,就提高了线程池的灵活性)。再定义一个线程池类ThreadPool,成员变量有定义线程池中线程的最大数量thr_max,一个任务缓冲队列_queue,一个互斥量_mutex,用于实现对缓冲队列的安全性,一个条件变量_cond,用于实现线程池中线程的同步。

threadpool.hpp文件

//threadpool.hpp
#include <iostream>
#include <cstdio>
#include <queue>
#include <stdlib.h>
#include <pthread.h>
using namespace std;typedef void (*handler_t)(int);
#define MAX_THREAD 5
//任务类
class ThreadTask
{public:ThreadTask(){}//将数据与处理方式打包在一起void setTask(int data, handler_t handler){_data = data;_handler = handler;}//执行任务函数void run(){return _handler(_data);}private:int _data;//任务中处理的数据handler_t _handler;//处理任务方式
};//线程池类
class ThreadPool
{public:ThreadPool(int thr_max = MAX_THREAD):_thr_max(thr_max){pthread_mutex_init(&_mutex, NULL);pthread_cond_init(&_cond, NULL);for (int i = 0; i < _thr_max; i++){pthread_t tid;int ret = pthread_create(&tid, NULL, thr_start, this);if (ret != 0){printf("thread create error\n");exit(-1);}}}~ThreadPool(){pthread_mutex_destroy(&_mutex);pthread_cond_destroy(&_cond);}bool taskPush(ThreadTask &task){pthread_mutex_lock(&_mutex);_queue.push(task);pthread_mutex_unlock(&_mutex);pthread_cond_signal(&_cond);return true;}//类的成员函数,有默认的隐藏参数this指针//置为static,没有this指针,static void *thr_start(void *arg){ThreadPool *p = (ThreadPool*)arg;while (1){pthread_mutex_lock(&p->_mutex);while (p->_queue.empty()){pthread_cond_wait(&p->_cond, &p->_mutex);}ThreadTask task;task =p-> _queue.front();p->_queue.pop();pthread_mutex_unlock(&p->_mutex);task.run();//任务的处理要放在解锁之外}return NULL;}private:int _thr_max;//线程池中线程的最大数量queue<ThreadTask> _queue;//任务缓冲队列pthread_mutex_t _mutex; //保护队列操作的互斥量pthread_cond_t _cond; //实现从队列中获取结点的同步条件变量
};

main.cpp

//main.cpp
#include <unistd.h>
#include "threadpool.hpp"//处理方法1
void test_func(int data)
{int sec = (data % 3) +1;printf("tid:%p -- get data:%d, sleep:%d\n", pthread_self(), data, sec);sleep(sec);
}//处理方法2
void tmp_func(int data)
{printf("tid:%p -- tmp_func\n", pthread_self());sleep(1);
}int main()
{ThreadPool pool;for (int i = 0; i < 10; i++){ThreadTask task;if (i % 2 == 0){task.setTask(i, test_func);}else{task.setTask(i, tmp_func);}pool.taskPush(task);}sleep(1000);return 0;
}

运行结果:线程池最多有5个线程,标注的每种颜色对应的是同一个线程,这样子就能完成通过几个线程,完成多个任务,而不是多个线程完成多个任务。创建和销毁的时间开销也节省了不少

Linux 线程池的概念与实现相关推荐

  1. linux线程池的使用

      Linux下通用线程池的创建与使用[ZT] 收藏 本文给出了一个通用的线程池框架,该框 架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执 ...

  2. linux线程池简单实例

    linux线程池简单实例 转载于:https://www.cnblogs.com/adong7639/p/5044685.html

  3. Linux系统编程41:多线程之线程池的概念及实现

    文章目录 (1)什么是线程池 (2)实现一个简单的线程池 (3)线程池优点 (1)什么是线程池 线程池是线程的一种使用模式.在前面的情况中,我们都是遇到任务然后创建线程进行再执行.但是线程的频繁创建就 ...

  4. 非常精简的Linux线程池实现(一)——使用互斥锁和条件变量

    https://blog.csdn.net/kxcfzyk/article/details/31719687 线程池的含义跟它的名字一样,就是一个由许多线程组成的池子. 有了线程池,在程序中使用多线程 ...

  5. linux线程池实现多线程并发,基于Linux的多线程池并发Web服务器设计-电子设计工程.PDF...

    基于Linux的多线程池并发Web服务器设计-电子设计工程.PDF 第 卷 第 期 电子设计工程 年 月 基于 的多线程池并发 服务器设计 陈 涛 任海兰 武汉邮电科学研究院 湖北 武汉 摘要 时至今 ...

  6. 一个简单的linux线程池

    线程池:简单地说,线程池 就是预先创建好一批线程,方便.快速地处理收到的业务.比起传统的到来一个任务,即时创建一个线程来处理,节省了线程的创建和回收的开销,响应更快,效率更高. 在linux中,使用的 ...

  7. java线程池的概念_Java线程池的基本概念以及生命周期

    一.为什么要实现线程池? 线程的创建与销毁对于CPU而言开销较大,通过池化技术可避免重复的创建与销毁线程. 方便与线程资源统一管理. 二.几种常见的线程池以及核心参数 不推荐使用Executor创建线 ...

  8. Linux线程池的设计

    我设计这个线程池的初衷是为了与socket对接的.线程池的实现千变万化,我得这个并不一定是最好的,但却是否和我心目中需求模型的.现把部分设计思路和代码贴出,以期抛砖引玉.个人比较喜欢搞开源,所以大家如 ...

  9. linux 线程池编程,Linux-C-9-线程池编程

    线程池 线程池:因为线程在频繁的进行创建和销毁过程中浪费CPU资源,线程池就是把一堆线程放在一个池子里面进行统一管理: 线程池工作流程: 1.初始化线程池,任务队列和工作线程: 2.向任务队列中添加任 ...

最新文章

  1. BGP 最佳路径选择之 -- Origin
  2. java gc的工作原理、如何优化GC的性能、如何和GC进行有效的交互
  3. python nltk 入门demo
  4. Openfiler的安装和配置
  5. java实现顺序栈_Java实现顺序栈原理解析
  6. 解决若干WTL与VS2010的兼容问题(如error MSB6006: “cmd.exe”)
  7. django中的Ajax文件上传
  8. 数据结构之图的应用:拓扑排序
  9. 动态代理:jdk和cglib区别
  10. 商业认知,新的一年已经开始,许多老板都制订了新的目标
  11. Halcon PDF文档(hdevelop_users_guide)学习总结之六——Halcon如何导出C++代码
  12. Javascript项目
  13. nodejs redis 发布订阅_「赵强老师」Redis的消息发布与订阅
  14. 蓝桥杯2018年第九届省赛-第几个幸运数
  15. 计算机word表格公开课ppt,word表格制作课件公开课.ppt
  16. 解决mac更新系统后git无法使用
  17. 定期存款怎么存定期存款怎么存?银行定期存款怎么存最划算?
  18. IMU(LPMS-B2)分析随机误差
  19. Asp.net设置Meta标签优化好你的页面
  20. 手动建库:按标准快速创建MDB数据库,快速创建Arcgis数据库。

热门文章

  1. 用74ls90组成二十四进制计数器_CD4017是什么?十进制计数器分频器CD4017的逻辑功能呢?...
  2. sql server一个查询语句引发的死锁
  3. 前端date format_前端面试-手撕代码篇
  4. Jsp+Ssh+Mysql实现的Java Web学生考勤管理
  5. vmware 虚拟机设置 redhat 桥接模式
  6. pyhton链式赋值在可变类型/不可变类型上的区别以及其本质
  7. 并发-阻塞队列源码分析
  8. tensorflow conv2d的padding解释以及参数解释
  9. Ubuntu(Deepin)搭建Android开发环境(Android Studio)
  10. 爱情七十一课,低调恋爱