C++版简单线程池
2016-05-07 13:45
633 查看
需求
之前写过一个C#版本的简单线程池http://blog.csdn.net/ylbs110/article/details/51224979由于刚刚学习了C++11新特性中的future,于是想到用它来实现一个线程池。
实现
思路基本和C#版本的一样,主要区别是委托的实现,线程句柄的不同和线程锁:本来C++有function模板,但是实现起来比较麻烦,这里主要是实现线程池,所以动态参数的委托就不实现了,直接使用typedef
void(*Func)();来实现一个无参数无返回值的函数指针
线程句柄使用future
线程锁使用mutex
关于future和mutex的用法在C++标准库第2版里面讲的很清楚,这里不细说。
与C#版本的实现方式类似,首先实现一个线程句柄类,该类主要用来存储线程池中运行的方法的句柄,并且实现对该方法的关闭操作,完成状态查询,循环状态查询等一系列功能。
线程池中使用队列来存储还未运行的方法,所有线程也使用一个队列存储起来。所有线程都运行一个run方法,该方法主要用来从线程句柄队列中提取任务然后运行。而提取任务的方法中需要使用mutex线程锁来防止多个线程提取任务时的冲突。
原理很简单,上代码吧:
PublicData
公共数据文件,本程序集中仅仅实现了一个Func指针#include "stdafx.h" typedef void(*Func)();
Thread
Thread.h#include "stdafx.h" #include <future> #include <chrono> #include "PublicData.h" using namespace std; class Thread { public: Thread(Func f = nullptr, int waitTime = 0, int cycleTime = -1); void setFunc(Func f, int waitTime = 0, int cycleTime = -1); Func getFunc(); bool cancel(); bool isCancel(); bool isDone(); void run(); private: int waitTime; int cycleTime; bool isCycle = false;; bool isRunning = false; bool iscancel = false; bool isdone = false; Func _func; };
Thread.cpp
#include "stdafx.h" #include "Thread.h" Thread::Thread(Func f, int waitTime, int cycleTime) :_func(f), waitTime(waitTime), cycleTime(cycleTime){ if (waitTime < 0) waitTime = 0; if (cycleTime <= 0) isCycle = false; } void Thread::setFunc(Func f, int waitTime, int cycleTime){ _func = f; this->waitTime = waitTime; this->cycleTime = cycleTime; }; Func Thread::getFunc(){ return _func; }; bool Thread::cancel(){ if (isdone) return false; else if (iscancel) return false; else if (isRunning && !iscancel) return false; else return iscancel = true; } bool Thread::isCancel(){ return iscancel; } bool Thread::isDone(){ return isdone; } void Thread::run(){ if (isdone) return; if (_func == nullptr) return; this_thread::sleep_for(chrono::milliseconds(waitTime)); if (iscancel) return; isRunning = true; if (isCycle){ (*_func)(); this_thread::sleep_for(chrono::milliseconds(cycleTime)); } else (*_func)(); isdone = true; }
ThreadPool
ThreadPool.h#pragma once #include "stdafx.h" #include <deque> #include <chrono> #include <future> #include <mutex> #include <exception> #include "PublicData.h" #include "Thread.h" using namespace std; class ThreadPool { public: ThreadPool(int i = 1); ~ThreadPool(); Thread create(Func f, int waitTime = -1, int cycleTime = -1); void shoutdown(); bool isShoutdown(); private: deque<Thread> threadDeque; deque<future<void>> futureDeque; mutex runMutex; int futureNum; Func getFunc(); void run(); };
ThreadPool.cpp
#include "stdafx.h" #include "ThreadPool.h" ThreadPool::ThreadPool(int i){ threadDeque = deque<Thread>(); futureDeque = deque<future<void>>(); futureNum = i; while (i-- > 0) { futureDeque.push_back(async(launch::async, [this]{ //run(); while (true) { if (threadDeque.size() > 0){ auto r = threadDeque.begin()->getFunc(); threadDeque.pop_front(); r(); } } })); } }; ThreadPool::~ThreadPool(){}; Thread ThreadPool::create(Func f, int waitTime, int cycleTime){ threadDeque.push_back(Thread(f, waitTime, cycleTime)); return threadDeque.back(); }; void ThreadPool::shoutdown(){ while (futureDeque.size()>0) { futureDeque.begin()->~future(); futureDeque.pop_front(); } while (threadDeque.size()>0) { threadDeque.begin()->cancel(); threadDeque.pop_front(); } }; bool ThreadPool::isShoutdown(){ return !(futureDeque.size() > 0); }; Func ThreadPool::getFunc(){ lock_guard<mutex> l(runMutex); auto r = threadDeque.begin()->getFunc(); threadDeque.pop_front(); return r; }; void ThreadPool::run(){ while (true) { if (threadDeque.size() > 0){ auto r = threadDeque.begin()->getFunc(); threadDeque.pop_front(); r(); } } };
转载请注明出处:http://blog.csdn.net/ylbs110/article/details/51337530
测试
测试方法
void showA(){ for (int i = 0; i < 500; i++) printf("a"); printf("\n"); } void showB(){ for (int i = 0; i < 500; i++) printf("b"); printf("\n"); } void showC(){ for (int i = 0; i < 500; i++) printf("c"); printf("\n"); } void showD(){ for (int i = 0; i < 500; i++) printf("d"); printf("\n"); }
调用
ThreadPool t=ThreadPool(5); Thread a = t.create(showA); Thread b = t.create(showB); Thread c = t.create(showC); Thread d = t.create(showD); system("pause"); return 0;
运行结果
aaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacccccccccccccccccccccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbb请 按任意键继续. . . bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddcccccccccccccccbbbbbbbbbbbbbbbbbbbbbbbbddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd cbbccccbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
从结果可以看出,四个线程执行输出的时候没有先后顺序,运行成功。
相关文章推荐
- [C++]OOP编程基本准则
- Leetcode 18. 4Sum
- 注释转换项目(c->c++)
- C++ 操作符重载
- C++(Qt)之尽可能延后定义式的出现时间
- 高效c/c++读书笔记
- 二进制中1的个数的多种解法解析以及完整c语言代码
- C语言malloc
- c语言不使用加号实现两个数的相加
- mono嵌入C++。运行失败
- nyoj 49 开心的小明
- C++: 位操作
- c++实验5-求和
- 二叉排序树C语言实现二
- 初识回调函数
- 构建复杂的应用程序(二)—— visual studio 下 C/C++ 项目开发
- 选择c++还是java,程序员如何提高研发技术?
- C++ 位运算
- C++学习笔记之九 循环和关系表达式
- 学好C语言的推荐途径