您的位置:首页 > 编程语言 > C语言/C++

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


从结果可以看出,四个线程执行输出的时候没有先后顺序,运行成功。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: