C++11简化线程池的实现
2015-12-27 16:50
417 查看
我想用C语言写过线程池的朋友因该都知道用C语言写一个线程池有多么的麻烦,代码差不多300行左右,而且不易阅读。记得大二寒假第一次写线程池用的就是C语言,当时先参考了别人用C写的代码,说实话看起来真困难,因为C写出来的结构好乱,代码又多。
我最近在实现一个自己的简单C++网络库(欢迎指点https://github.com/Miaoshuai/netlib),需要一个线程池,本来可以直接用之前拿C写的那个,但我不太想用那个,于是我就结合C++11一些新特新写了一个代码很少,阅读起来更简单的线程池,在这里分享给大家
线程池类的定义
线程池类的实现
线程池的测试代码
请读者自行测试
需要注意的是当我们的任务函数的参数非空时,我们只需用C++11的std::bind绑定一下其参数即可
具体实例
我最近在实现一个自己的简单C++网络库(欢迎指点https://github.com/Miaoshuai/netlib),需要一个线程池,本来可以直接用之前拿C写的那个,但我不太想用那个,于是我就结合C++11一些新特新写了一个代码很少,阅读起来更简单的线程池,在这里分享给大家
线程池类的定义
#ifndef THREAD_POOL_H_ #define THREAD_POOL_H_ #include <thread> #include <mutex> #include <condition_variable> #include <list> #include <vector> #include <memory> #include <functional> namespace netlib { class ThreadPool { public: typedef std::function<void(void)> Task; ThreadPool(int threadNumber); ~ThreadPool(); //往任务队列里添加任务 bool append(Task task); //启动线程池 bool start(void); //停止线程池 bool stop(void); private: //线程所执行的工作函数 void threadWork(void); std::mutex mutex_; //互斥锁 std::condition_variable_any condition_empty_; //当任务队列为空时的条件变量 std::list<Task> tasks_; //任务队列 bool running_; //线程池是否在运行 int threadNumber_; //线程数 std::vector<std::shared_ptr<std::thread>> threads_; //用来保存线程对象指针 }; } #endif
线程池类的实现
#include "thread_pool.h" #include <stdio.h> #include <thread> #include <mutex> #include <memory> #include <functional> #include <unistd.h> using namespace netlib; ThreadPool::ThreadPool(int threadNumber) :threadNumber_(threadNumber), running_(true), threads_(threadNumber_) { } ThreadPool::~ThreadPool() { if(running_) { stop(); } } bool ThreadPool::start(void) { for(int i = 0; i < threadNumber_; i++) { threads_.push_back(std::make_shared<std::thread>(std::bind(&ThreadPool::threadWork,this)));//循环创建线程 } usleep(500); printf("线程池开始运行\n"); return true; } bool ThreadPool::stop(void) { if(running_) { running_= false; for(auto t : threads_) { t->join(); //循环等待线程终止 } } return true; } bool ThreadPool::append(Task task) { std::lock_guard<std::mutex> guard(mutex_); tasks_.push_front(task); //将该任务加入任务队列 condition_empty_.notify_one();//唤醒某个线程来执行此任务 return true; } void ThreadPool::threadWork(void) { Task task = NULL; while(running_) { { std::lock_guard<std::mutex> guard(mutex_); if(tasks_.empty()) { condition_empty_.wait(mutex_); //等待有任务到来被唤醒 } if(!tasks_.empty()) { task = tasks_.front(); //从任务队列中获取最开始任务 tasks_.pop_front(); //将取走的任务弹出任务队列 } else { continue; } } task(); //执行任务 } }
线程池的测试代码
#include <iostream> #include <vector> #include <string> #include <functional> #include "thread_pool.h" #include <unistd.h> void fun(void) { std::cout<<"hello"<<std::endl; } int main(int argc,char **argv) { netlib::ThreadPool pool(10); pool.start(); while(1) { pool.append(fun); } return 0; }
请读者自行测试
需要注意的是当我们的任务函数的参数非空时,我们只需用C++11的std::bind绑定一下其参数即可
具体实例
#include <iostream> #include <vector> #include <string> #include <functional> #include "thread_pool.h" #include <unistd.h> void fun(std::string s) { std::cout<<s<<std::endl; } int main(int argc,char **argv) { netlib::ThreadPool pool(10); pool.start(); while(1) { pool.append(std::bind(fun,std::string("hello"))); } return 0; }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C#多线程学习之(四)使用线程池进行多线程的自动管理
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性