码迷,mamicode.com
首页 > 编程语言 > 详细

C++版简单线程池

时间:2016-05-13 04:06:08      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:

需求

之前写过一个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++版简单线程池

标签:

原文地址:http://blog.csdn.net/ylbs110/article/details/51337530

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!