C++封装POSIX 线程库(六)线程池
来源:互联网 发布:淘宝购物省钱技巧 编辑:程序博客网 时间:2024/06/03 14:07
线程池有两个主要组件:
1.threads
2.blocking queue
解决的问题是线程创建与销毁带来的开销和通过线程池实现伪异步
过程类似于简单的生产者消费者问题(详见wiki)
Blocking Queue
对应用户添加任务CallBack和线程拿任务执行两个操作,因此需要两个条件变量和一个互斥锁
如果把用户添加任务比做生产者,线程拿任务比做消费者..那么需要两个条件变量就解决了
1.生产者>消费者(防止”撑爆”任务队列)
2.生产者<消费者(没有任务可执行时线程会挂起)
Threads
线程池由一组线程组成,构造阶段创建一组线程并挂起,每当添加一个任务的时候就notify一个线程执行…
当线程池析构的时候,将这些线程回收….这里有个很大的坑…
代码
完整代码:https://github.com/NearXdu/ThreadPool
#ifndef __THREADPOLL_H__#define __THREADPOLL_H__#include "MutexLock.h"#include "Condition.h"#include "Thread.h"#include <boost/noncopyable.hpp>#include <boost/function.hpp>#include <boost/bind.hpp>#include <boost/ptr_container/ptr_vector.hpp>#include <queue>class ThreadPool : boost::noncopyable{ public: typedef boost::function<void()>Task; ThreadPool(size_t qsize,size_t nthreads); ~ThreadPool(); void start(); void stop(); void addTask(Task t); Task getTask(); bool isStarted()const{return isStarted_;} void runInThread(); private: mutable MutexLock mutex_; Condition notEmpty_;//blocking queue full条件变量 Condition notFull_;//blocking queue empty 条件变量 size_t queueSize_;//任务队列大小 std::queue<Task> queue_;//任务队列 size_t threadsNum_;//线程数目 boost::ptr_vector<Thread> threads_;//线程池中的线程 volatile bool isStarted_;};#endif///////////////////////////////////#include "ThreadPool.h"ThreadPool::ThreadPool(size_t q,size_t n) :mutex_(), notEmpty_(mutex_), notFull_(mutex_), queueSize_(q), threadsNum_(n), isStarted_(false){}ThreadPool::~ThreadPool(){ if(isStarted_) { stop(); }}void ThreadPool::stop(){ { MutexLockGuard lock(mutex_); isStarted_ = false; notEmpty_.notifyAll(); //激活所有的线程 } for_each(threads_.begin(), threads_.end(), boost::bind(&Thread::join, _1));}void ThreadPool::addTask(Task t){ if(threads_.empty()) { t(); } else { MutexLockGuard lock(mutex_); while(queue_.size()>=queueSize_&&isStarted_) notFull_.wait(); if(!isStarted_) return ; queue_.push(std::move(t)); notEmpty_.notify(); }}ThreadPool::Task ThreadPool::getTask(){ MutexLockGuard lock(mutex_); while(queue_.empty()&&isStarted_) { notEmpty_.wait(); } Task t; if(!queue_.empty()) { assert(!queue_.empty()); t=queue_.front(); queue_.pop(); notFull_.notify(); } return t;}void ThreadPool::runInThread(){ while(isStarted_) { // std::cout<<"hello runinThread"<<std::endl; Task t(getTask());//will blocked until "add" ops //assert(t!=NULL); if(t) { t();//run } }}void ThreadPool::start(){ isStarted_=true; threads_.reserve(threadsNum_); for(size_t i=0;i<threadsNum_;++i) { threads_.push_back( new Thread(boost::bind( &ThreadPool::runInThread,this))); threads_[i].start(); }}
阅读全文
1 0
- C++封装POSIX 线程库(六)线程池
- C++封装POSIX 线程库(三)线程的封装
- C++封装POSIX 线程库(一)互斥锁的封装
- C++ 封装POSIX线程
- C++封装POSIX 线程库(五)实现CountDownLatch
- C++封装POSIX 线程库(四)使用封装的线程
- C++封装POSIX 线程库(二)条件变量的封装
- POSIX pthread线程库的封装-主动对象
- POSIX多线程程序设计学习篇之六(线程属性)
- POSIX线程库
- posix线程库1
- posix线程库<一>
- POSIX线程(1)
- POSIX线程(2)
- posix 线程(一)
- POSIX线程库API(全)(上)
- POSIX线程库API(全)(下)
- POSIX线程库API(全)
- GeoServer之SqlView
- java基本类型转换
- 递归实现前n项和(两种方法)
- thinkphp事务处理
- Liunx基础命令(2)
- C++封装POSIX 线程库(六)线程池
- 我所理解的依赖注入IOC
- Linux_Nginx_Tomcat 安装笔记
- 使用certbot续期ssl证书renew时遇到问题
- Mxnet图片分类(3)fine-tune
- Kotlin 官方学习教程之返回和跳转
- 标准IO与文件IO 的区别
- 栈的实现
- Android 获取栈最顶层Activity和Application Context解决方案