C++版简单线程池

需求

之前写过一个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

从结果可以看出,四个线程执行输出的时候没有先后顺序,运行成功。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要实现一个简单线程池,可以参考以下步骤和代码示例: 1. 首先,创建一个ThreadPool类,并包含必要的头文件和成员变量。引用中的代码提供了一个简单线程池类的实现,其中包括线程队列、任务队列、互斥锁和条件变量等。 2. 在构造函数中初始化线程池,设置最小线程数和最大线程数,并创建工作线程和管理者线程。引用中的代码示例展示了如何初始化线程池,包括创建线程、启动工作线程和管理者线程。 3. 实现添加任务的方法,用于向任务队列中添加任务。这个方法将会唤醒等待的线程进行任务的执行。例如,在ThreadPool类中实现addTask方法,将任务添加到任务队列中。 4. 实现任务的执行方法。这个方法被工作线程调用,从任务队列中获取任务并执行。可以在ThreadPool类中实现runTask方法来执行任务。引用中的代码示例展示了如何执行任务。 5. 实现线程池的关闭方法。这个方法将会关闭线程池,并等待所有线程退出。在ThreadPool类中实现stop方法,用于关闭线程池。可以通过设置标志位来控制线程的退出,等待所有线程退出后再回收资源。 综上所述,C语言中可以通过使用互斥锁、条件变量和线程创建函数来实现一个简单线程池。在构造函数中初始化线程池,包括创建工作线程和管理者线程。通过添加任务和执行任务的方法,实现对任务的管理和执行。最后,通过关闭线程池的方法来退出所有线程并回收资源。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++ 实现一个简易的线程池](https://blog.csdn.net/junmangbo4166/article/details/104806037)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [一文带你使用c++实现线程池!!!](https://blog.csdn.net/qq_44778436/article/details/128497327)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值