这里给出一个简单的C++线程池包装类,该类具有的特点是:

1.线程池大小是固定的, 一创建后,就不具有伸缩特性. 一般建议是 CPU核心数的2倍或1倍.

2.简单但是很可靠.

3.资源占用极低. 在开启100个线程时, 4核CPU的占用率只有20%不到, 30个线程时, 占用7%以下.实践证明, 使用信号量和互斥锁进行多线程的同步是最合理高效的方法, 比sleep让出cpu要好很多.

后续需要增加的功能是, 线程个数的动态伸缩, 任务处理的超时机制. 当然, 在实际探索中发现高级功能的线程池并不能优雅退出, 这是困扰我很久的问题. 所以, 这里只给出最简单可靠的代码.

运行环境:

Ubuntu 14.04 64bit LTS

头文件thread_pool.h

#ifndef __THREAD_POOL_H__
#define __THREAD_POOL_H__#include <stdio.h>
#include <pthread.h>
#include <assert.h>
#include <iostream>
#include <list>using namespace std;class CJob{public:CJob(void* (*r)(void* arg), void* a): callback_routine(r), arg(a){}~CJob(){}void* (*callback_routine) (void* arg);void* arg;
};//fixed size thread pool
class CThreadPool{public:CThreadPool(int max_th_num);~CThreadPool();int pool_add_job(void* (*process)(void* arg), void* arg);pthread_mutex_t      queue_mutex;pthread_cond_t       queue_cond;list<CJob*>          queue_job;pthread_t*           thread_vec;int                  max_thread_num;int                  cur_queue_size;int                  shutdown;
};#endif

源文件thread_pool.cpp

#include "thread_pool.h"static void* thread_routine(void* arg){CThreadPool* pool = (CThreadPool*)arg;if(pool == NULL) return NULL;printf("starting thread [%lu]\n", pthread_self());while(1){pthread_mutex_lock(&pool->queue_mutex);while (pool->cur_queue_size == 0 && !pool->shutdown){printf("thread [%lu] is waiting\n", pthread_self());pthread_cond_wait(&pool->queue_cond, &pool->queue_mutex);}if(pool->shutdown){printf("thread [%lu] will exit\n", pthread_self());pthread_mutex_unlock(&pool->queue_mutex);pthread_exit(NULL);}printf("thread [%lu] is starting to work\n", pthread_self());assert (pool->cur_queue_size != 0);assert (!pool->queue_job.empty());pool->cur_queue_size--;CJob* job = pool->queue_job.front();pool->queue_job.pop_front();pthread_mutex_unlock(&pool->queue_mutex);(*job->callback_routine) (job->arg);delete job;}
}CThreadPool::CThreadPool(int max_th_num): cur_queue_size(0), shutdown(0), max_thread_num(max_th_num){pthread_mutex_init(&queue_mutex, NULL);pthread_cond_init(&queue_cond, NULL);thread_vec = new pthread_t[max_thread_num];for(int i = 0; i < max_thread_num; i++){pthread_create(&thread_vec[i], NULL, thread_routine, (void*)this);}
}CThreadPool::~CThreadPool(){if(shutdown) return;shutdown = 1;pthread_cond_broadcast(&queue_cond);for(int i=0; i < max_thread_num; i++)pthread_join(thread_vec[i], NULL);delete [] thread_vec;for(list<CJob*>::iterator it = queue_job.begin(); it != queue_job.end(); ++it)delete *it;queue_job.clear();pthread_mutex_destroy(&queue_mutex);pthread_cond_destroy(&queue_cond);
}int CThreadPool::pool_add_job(void* (*process)(void* arg), void* arg){CJob* job = new CJob(process, arg);pthread_mutex_lock(&queue_mutex);queue_job.push_back(job);cur_queue_size++;pthread_mutex_unlock(&queue_mutex);pthread_cond_signal(&queue_cond);return 0;
}

测试文件test_pool.cpp

//g++ -g test_pool.cpp thread_pool.cpp -o test_pool -lpthread
//
#include <unistd.h>
#include "thread_pool.h"void* job_process(void* arg){printf("thread [%lu], working on task [%d]\n", pthread_self(), *(int*)arg);usleep(1000 * 1000);return NULL;
}int main(int argc, char* argv[]){CThreadPool* pool = new CThreadPool(100);int* jobNo = new int[10000];for(int i = 0; i < 10000; i++){jobNo[i] = i;pool->pool_add_job(job_process, &jobNo[i]);}usleep(100 * 1000 * 1000);delete pool;delete [] jobNo;return 0;
}

测试截图

欢迎批评指正.

简单C++线程池包装类源码示例相关推荐

  1. 【Android 异步操作】线程池 ( 线程池作用 | 线程池种类 | 线程池工作机制 | 线程池任务调度源码解析 )

    文章目录 一.线程池作用 二.线程池种类 三.线程池工作机制 四.线程池任务调度源码解析 一.线程池作用 线程池作用 : ① 避免创建线程 : 避免每次使用线程时 , 都需要 创建线程对象 ; ② 统 ...

  2. Java并发编程实战(chapter_3)(线程池ThreadPoolExecutor源码分析)

    为什么80%的码农都做不了架构师?>>>    这个系列一直没再写,很多原因,中间经历了换工作,熟悉项目,熟悉新团队等等一系列的事情.并发课题对于Java来说是一个又重要又难的一大块 ...

  3. Java线程池状态判断源码_深入浅出Java线程池:源码篇

    前言 在上一篇文章深入浅出Java线程池:理论篇中,已经介绍了什么是线程池以及基本的使用.(本来写作的思路是使用篇,但经网友建议后,感觉改为理论篇会更加合适).本文则深入线程池的源码,主要是介绍Thr ...

  4. idea 线程内存_Java线程池系列之-Java线程池底层源码分析系列(一)

    课程简介: 课程目标:通过本课程学习,深入理解Java线程池,提升自身技术能力与价值. 适用人群:具有Java多线程基础的人群,希望深入理解线程池底层原理的人群. 课程概述:多线程的异步执行方式,虽然 ...

  5. idea 线程内存_Java线程池系列之-Java线程池底层源码分析系列(二)

    课程简介: 课程目标:通过本课程学习,深入理解Java线程池,提升自身技术能力与价值. 适用人群:具有Java多线程基础的人群,希望深入理解线程池底层原理的人群. 课程概述:多线程的异步执行方式,虽然 ...

  6. 从原理到实现丨手把手教你写一个线程池丨源码分析丨线程池内部组成及优化

    人人都能学会的线程池 手写完整版 1. 线程池的使用场景 2. 线程池的内部组成 3. 线程池优化 [项目实战]从原理到实现丨手把手教你写一个线程池丨源码分析丨线程池内部组成及优化 内容包括:C/C+ ...

  7. JAVA线程池(ThreadPoolExecutor)源码分析

    JAVA5提供了多种类型的线程池,如果你对这些线程池的特点以及类型不太熟悉或者非常熟悉,请帮忙看看这篇文章(顺便帮忙解决里面存在的问题,谢谢!):     http://xtu-xiaoxin.ite ...

  8. [转载] Java线程池框架源码分析

    转载自http://www.linuxidc.com/Linux/2014-11/108791.htm 相关类Executor,Executors,AbstractExecutorService,Ex ...

  9. c++ 线程池_JAVA并发编程:线程池ThreadPoolExecutor源码分析

    前面的文章已经详细分析了线程池的工作原理及其基本应用,接下来本文将从底层源码分析一下线程池的执行过程.在看源码的时候,首先带着以下两个问题去仔细阅读.一是线程池如何保证核心线程数不会被销毁,空闲线程数 ...

最新文章

  1. 远程计算机串口控制软件,智能控制的设备上使用远程开关需要用到RS485串口继电器、网关、电脑平台...
  2. 错误:java.lang.Illegal Argument Exception: Document base F:/apache-tomcat-7.0.40/webapps/ web3 does no
  3. 三网齐发 HTC One行货确定4月24日发布
  4. android jni示例_Android动画示例
  5. 《数据科学:R语言实现》—— 第1章 R中的函数 1.1 引言
  6. 查看服务器sftp用户信息,linux查看sftp服务器配置
  7. 男怕入错行 完美池宇峰畅谈创业点滴
  8. FPGA芯片供电总结
  9. 一只小白,在学习delphi.感觉很吃力。。
  10. linux命令操作改变图片大小,使用linux命令调整图片大小、格式等
  11. 如何在 Ubuntu 中禁用 motd 欢迎消息
  12. matlab roundn函数_columns函数的使用方法 matlab中round函数具体用法
  13. requests.exceptions.SSLError: HTTPSConnectionPool(host='XXX', port=443)问题
  14. uniapp使用第三方字体
  15. AVR单片机开发1——IO口的输入和输出
  16. SAP ABAP ASSIGNED 用法
  17. 如何用r语言分析数据
  18. 简单工厂和抽象工厂有什么区别?
  19. 【Python】配置Python环境
  20. android 收音机调频,FM手机调频收音机

热门文章

  1. Integer vs int
  2. Android ActionBarDrawerToggle、DrawerLayout、ActionBar 结合
  3. (一三〇)UITextField的光标操作扩展
  4. [翻译]自动维护索引重新生成组织的SQL批处理语句
  5. php sendmail方法,PHP实现在windows下配置sendmail并通过mail()函数发送邮件的方法
  6. python减少内存_如何降低 Python 的内存消耗量?
  7. c cin.get()的用法小结_c语言中static 用法
  8. mysql cert_Mysql使用SSL连接
  9. 永州科技学院有计算机专业吗,永州科技学院有哪些专业
  10. xuanke java_wangshangxuankexitong - WEB源码|JSP源码/Java|源代码 - 源码中国