C++线程池的简单实现 [Java风格]

1:简介

本文基于C++11,实现的线程池功能实现相当于java中核心数线程为size,最大线程数为size,任务队列为无界队列的ThreadPoolExecutor线程池,且简化了,直接一次性生产出size数量的线程。凡是继承了Runnable接口的任务都可以提交到该线程池中。任务队列也模仿Java的BlockingQueue阻塞队列。

2:C++版本的BlockingQueue

主要采用C++11的条件变量std::condition_variable来实现。

BlockingQueue.hpp

#include <queue>
#include <mutex>
#include <condition_variable>

/**
 * 阻塞队列
 * @tparam T 任意类型
 */
template<typename T>
class BlockingQueue {
private:
    std::queue<T> queue;//队列
    std::mutex mutex;//互斥锁
    std::condition_variable conditionVariable;
public:
    //把Object加到BlockingQueue里
    void put(const T &t) {
        std::unique_lock<std::mutex> lock(mutex);//加上互斥锁
        queue.push(t);
        conditionVariable.notify_one();//释放互斥锁,通知等待线程
    }

    //取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入
    T take() {
        std::unique_lock<std::mutex> lock(mutex);//互斥锁加上
        if (queue.empty()) {
            //若队列为空,则等待互斥锁,当调用wait方法时会unlock
            conditionVariable.wait(lock);
        }
        T t = queue.front();
        queue.pop();
        return t;
    }

};

3:C++版本的Runnable接口

用纯虚函数来表示

Runnable.hpp

class Runnable {
public:
    virtual void run() = 0;
};

3:ThreadPoolExecutor

基本思路:基于上面实现的BlockingQueue阻塞队列来实现任务队列,线程池中线程会去任务队列中取任务来执行,如果没任务,则等待,若任务队列中有任务了,则唤醒一个等待线程去执行该任务。

#include <vector>
#include <thread>
#include <algorithm>
#include "BlockingQueue.hpp"
#include "Runnable.hpp"

//相当于ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue workQueue,RejectedExecutionHandler handler)
//corePoolSize:线程池核心线程数量size
//maximumPoolSize:线程池最大线程数量size
//且简化了,直接一次性生产size数量的线程
class ThreadPoolExecutor {
private:
    std::vector<std::thread> workers;//线程工作组
    BlockingQueue<std::shared_ptr<Runnable>> taskQueue;//任务队列

    volatile bool stop;

public:

    //构造线程池,同时启动它
    ThreadPoolExecutor(int size) : stop(false) {
        for (int i = 0; i < size; ++i) {
            workers.emplace_back([this] {
                while (!stop) {
                    taskQueue.take()->run();
                }
            });
        }
    }

    /**
     * 提交一个任务
     * @param task
     */
    void submit(std::shared_ptr<Runnable> task) {
        taskQueue.put(task);
    }

    /**
     * 析构的时候需要让线程正常退出
     */
    ~ThreadPoolExecutor() {
        this->stop = true;
        //等待run方法正常结束
        std::for_each(
                workers.begin(),
                workers.end(),
                [](std::thread &t) { t.join(); }
        );
    }
};

4:测试代码

main.cpp

#include <iostream>
#include "Runnable.hpp"
#include "ThreadPoolExecutor.hpp"
#include <thread>
#include <memory>

class TestRunnun1 : public Runnable {
public:
    void run() {
        for (int i = 0; i < 1000; ++i) {
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
            if (i % 50 == 0) {
                std::cout << "hello!! thread1...." << std::this_thread::get_id() << std::endl;
            }

        }
        std::cout << "hello!! thread1...." << std::this_thread::get_id() << std::endl;
    }
};

class TestRunnun2 : public Runnable {
public:
    void run() {
        for (int i = 0; i < 1000; ++i) {
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
            if (i % 50 == 0) {
                std::cout << "hello!! thread3...." << std::this_thread::get_id() << std::endl;
            }
        }
        std::cout << "hello!! thread3...." << std::this_thread::get_id() << std::endl;
    }
};


int main() {

    ThreadPoolExecutor executor(2);
    
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    executor.submit(std::make_shared<TestRunnun1>());
    executor.submit(std::make_shared<TestRunnun1>());
    executor.submit(std::make_shared<TestRunnun2>());
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    executor.submit(std::make_shared<TestRunnun1>());
    executor.submit(std::make_shared<TestRunnun2>());
    
    std::cout << "Hello, World!" << std::endl;
    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值