C++同异步极致线程池

不废话直接贴源码 综合,极简,好用易懂:

ThreadPool.hpp  支持静态类  仿函数 lambda  根据情况自己抄去改

#pragma once
#include <iostream>
#include <stdexcept>
#include <memory>
#include <vector>
#include <queue>
#include <thread>
#include <atomic>
#include <condition_variable>
#include <future>
#include <functional>

class ThreadPool
{
    using Task = std::function<void(void)>; //回调函数类型
    std::vector<std::thread> workers;       //工作线程
    std::queue<Task> tasks;                 //回调函数
    std::condition_variable condition;      //必须与unique_lock配合使用
    std::mutex queMutex;
    std::atomic_bool bStop;
    const int MAX_THREADS = 1000;           //最大线程数目
public:
    using Type = enum class _type{ Sync = 0, ASync };
    Type eType;

    //默认开一个线程 tp=Sync同步方式,=ASync异步方式
    ThreadPool(size_t threads = 1, Type tp= Type::Sync) :bStop(false), eType(tp)
    {
        if (threads <= 0 || threads > MAX_THREADS)
            throw std::exception();
        for (size_t i = 1; i <= threads; i++)
        {
            workers.emplace_back([this]
                {
                    while (!bStop)
                    {
                        Task task;
                        {
                            std::unique_lock<std::mutex> lock(this->queMutex);
                            this->condition.wait(lock, [this] {return this->bStop || !this->tasks.empty(); });
                            if (this->bStop && this->tasks.empty())
                                return;
                            task = std::move(this->tasks.front());
                            this->tasks.pop();
                        }
                        task();
                    }
                });
        }
    };

    //析构
    inline ~ThreadPool(void)
    {
        {
            std::unique_lock<std::mutex> lock(queMutex);
            bStop = true;
        }
        condition.notify_all();
        for (auto& worker : workers)
            worker.join();

        //计时方法
        //time_t start = GetTickCount64();
        //std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        //std::cout << "usetime:" << GetTickCount64() - start << " mm" << std::endl;
    };

    //同步方式添加队列
    template<class F, class... Args>
    bool append(F&& f, Args&& ... args)
    {
        if (eType != Type::Sync)
            throw std::runtime_error("not Sync Thread!");
        //操作工作队列时一定要加锁,因为他被所有线程共享
        queMutex.lock();        //同一个类的锁
        tasks.emplace(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
        queMutex.unlock();
        condition.notify_one(); //线程池添加进去了任务,自然要通知等待的线程
        return true;
    };

    //异步方式添加队列
    template<class F, class... Args>
    auto enqueue(F&& f, Args&& ... args) -> std::future<typename std::result_of<F(Args...)>::type>
    {
        if (eType != Type::ASync)
            throw std::runtime_error("not ASync Thread!");
        using return_type = typename std::result_of<F(Args...)>::type;
        auto task = std::make_shared<std::packaged_task<return_type()>>
            (std::bind(std::forward<F>(f), std::forward<Args>(args)...));
        std::future<return_type> res = task->get_future();
        {
            std::unique_lock<std::mutex> lock(queMutex);
            if (bStop)
                throw std::runtime_error("enqueue on stopped ThreadPool");
            tasks.emplace([task]()
                {
                    (*task)();
                });
        }
        condition.notify_one();
        return res;
    };
};

实例的测试hellothread.cpp

#include <stdio.h>
#include <iostream>
#include "ThreadPool.hpp"

//静态任务类
struct work
{
    static int process(int num)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        std::cout << "task >>>>>>>>>>> " << num << std::endl;
        return num;
    };
};

//仿函数
struct func
{
    int operator()(int num)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        std::cout << "task >>>>>>>>>>> " << num << std::endl;
        return num;
    };
};

//Lambda表达式 注意后面使用直接表达式也是可以用[]直接捕获
auto lambdaFun = [](int num)
{
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    std::cout << "task >>>>>>>>>>> " << num << std::endl;
    return num;
};

int main(void)
{
    //同步方式线程池
    ThreadPool syncPool(10, ThreadPool::Type::Sync);
    for (int i = 1; i <= 200; i++)
    {
        std::cout << "sync send++++" << std::endl;
        //Lambda表达式
        syncPool.append(lambdaFun, i);
        //静态类传参数
        syncPool.append(std::bind(&work::process, i));
        //仿函数
        syncPool.append(std::bind(func{}, i));
        std::this_thread::sleep_for(std::chrono::milliseconds(2));
    }

    //异步方式线程池
    ThreadPool asyncPool(10, ThreadPool::Type::ASync);
    std::vector<std::future<int>> results;
    for (int i = 1; i <= 200; i++)
    {
        std::cout << "async send++++" << std::endl;
        //Lambda表达式
        results.emplace_back(asyncPool.enqueue(lambdaFun,i));
        //静态类传参数
        results.emplace_back(asyncPool.enqueue(std::bind(&work::process, i)));
        //仿函数
        results.emplace_back(asyncPool.enqueue(std::bind(func{}, i)));
        std::this_thread::sleep_for(std::chrono::milliseconds(2));
    }
    for (auto&& result : results)
        std::cout << result.get() << '|';

    std::cout << "end---------" <<std::endl;;
    std::this_thread::sleep_for(std::chrono::hours(100));
}

g++11 编译(vs2022同理)

g++ hellothread.cpp -std=c++20 -DWIN32_LEAN_AND_MEAN -I/include -I./src -o hellothread.exe

相关推荐

  1. C++异步极致线

    2023-12-09 08:32:01       63 阅读
  2. 异步线

    2023-12-09 08:32:01       22 阅读
  3. c++ 实现线、实现异步接口

    2023-12-09 08:32:01       32 阅读
  4. C-线

    2023-12-09 08:32:01       39 阅读
  5. SpringBoot 线异步调用

    2023-12-09 08:32:01       43 阅读
  6. linux C 线

    2023-12-09 08:32:01       52 阅读
  7. 线设计---C++

    2023-12-09 08:32:01       44 阅读
  8. 线,我的异常呢?

    2023-12-09 08:32:01       43 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-09 08:32:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-09 08:32:01       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-09 08:32:01       82 阅读
  4. Python语言-面向对象

    2023-12-09 08:32:01       91 阅读

热门阅读

  1. ELK架构监控MySQL慢日志

    2023-12-09 08:32:01       60 阅读
  2. 线程安全与并发区别

    2023-12-09 08:32:01       59 阅读
  3. 晶闸管是什么

    2023-12-09 08:32:01       56 阅读
  4. linux如何删除大文件的第一行(sed)

    2023-12-09 08:32:01       56 阅读
  5. linux如何清空文件内容

    2023-12-09 08:32:01       69 阅读
  6. 智能手机IC

    2023-12-09 08:32:01       60 阅读
  7. 2023-12-08 工作心得

    2023-12-09 08:32:01       50 阅读
  8. Qt12.8

    Qt12.8

    2023-12-09 08:32:01      55 阅读
  9. MongoDB数据建模与文档设计

    2023-12-09 08:32:01       52 阅读
  10. uniapp封装websocket文件(app、h5兼容)

    2023-12-09 08:32:01       63 阅读
  11. git 命令

    2023-12-09 08:32:01       46 阅读