c++线程池

cpp 复制代码
// 引入必要的头文件
#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <atomic>
#include <string>
using namespace std;

// 定义一个任务类,封装了要执行的函数和参数
class Task {
public:
    // 使用可变参数模板和完美转发构造函数
    template<typename F, typename... Args>
    Task(F&& f, Args&&... args) {
        // 使用lambda表达式和std::bind将函数和参数绑定在一起
        func = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
    }

    // 执行任务
    void run() {
        func();
    }

private:
    // 使用std::function存储可调用对象
    std::function<void()> func;
};

// 定义一个线程池类,管理一组线程和一个任务队列
class ThreadPool {
public:
    // 构造函数,初始化线程池
    ThreadPool(size_t size) : stop(false) {
        // 根据指定的大小创建线程
        for (size_t i = 0; i < size; i++) {
            // 使用lambda表达式作为线程函数
            workers.emplace_back([this] {
                // 循环执行任务,直到线程池停止
                while (true) {
                    // 定义一个任务指针
                    Task* task;
                    // 使用互斥锁保护任务队列的访问
                    {
                        std::unique_lock<std::mutex> lock(this->queue_mutex);
                        // 使用条件变量等待任务的到来,或者线程池的停止
                        this->condition.wait(lock, [this] {
                            return this->stop || !this->tasks.empty();
                            });
                        // 如果线程池停止,并且任务队列为空,就退出循环
                        if (this->stop && this->tasks.empty()) {
                            return;
                        }
                        // 从任务队列中取出一个任务
                        task = this->tasks.front();
                        this->tasks.pop();
                    }
                    // 执行任务
                    task->run();
                    // 释放任务的内存
                    delete task;
                }
                });
        }
    }

    // 析构函数,销毁线程池
    ~ThreadPool() {
        // 使用互斥锁保护stop变量的访问
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            // 设置stop为true,表示线程池要停止
            stop = true;
        }
        // 通知所有等待的线程
        condition.notify_all();
        // 等待所有线程结束
        for (std::thread& worker : workers) {
            worker.join();
        }
    }

    // 向任务队列中添加一个任务
    template<typename F, typename... Args>
    void enqueue(F&& f, Args&&... args) {
        // 创建一个任务对象,使用new分配内存
        Task* task = new Task(std::forward<F>(f), std::forward<Args>(args)...);
        // 使用互斥锁保护任务队列的访问
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            // 将任务添加到队列中
            tasks.push(task);
        }
        // 通知一个等待的线程
        condition.notify_one();
    }

private:
    // 一组工作线程
    std::vector<std::thread> workers;
    // 一个任务队列
    std::queue<Task*> tasks;
    // 一个互斥锁,用于同步对任务队列的访问
    std::mutex queue_mutex;
    // 一个条件变量,用于等待和通知任务的到来
    std::condition_variable condition;
    // 一个原子布尔变量,用于表示线程池是否要停止
    std::atomic<bool> stop;
};


// 定义一个简单的函数,用于打印一些信息
void print_info(std::thread::id id, const std::string& msg) {
    // 使用互斥锁保护标准输出的访问
    static std::mutex cout_mutex;
    std::unique_lock<std::mutex> lock(cout_mutex);
    // 打印线程的id和信息
    std::cout << "Thread " << id << ": " << msg << std::endl;
}

// 定义一个main函数,用于测试线程池
int main() {
    // 创建一个大小为4的线程池
    ThreadPool pool(4);
    // 向线程池中添加10个任务
    for (int i = 0; i < 10; i++) {
        // 使用lambda表达式作为任务的函数
        pool.enqueue([i] {
              std::thread::id id = std::this_thread::get_id();
            // 调用print_info函数,传递当前线程的id和一个信息
            print_info(id, "Hello from task " + std::to_string(i));
            });
    }
    // 等待线程池的析构,自动结束所有线程
    return 0;
}
相关推荐
八角.。8 小时前
面向对象-多态
java·开发语言
@卓越俊逸_角立杰出@8 小时前
快速学会 Java 实现意图识别:从规则匹配到 BiLSTM 分类器
java·开发语言·人工智能
小小龙学IT8 小时前
simdjson:利用 SIMD 指令实现 GB/s 级 JSON 解析的 C++ 开源库
开发语言·c++·json
AndrewHZ8 小时前
【LLM技术全景】RAG 从原理到实战——检索增强生成完整指南
人工智能·深度学习·算法·llm·检索增强·生成式模型·rag
LuminousCPP8 小时前
单链表专题(三)-刷题复盘篇:从快慢指针到环形链表 II 数学推导
数据结构·经验分享·笔记·学习·算法·链表
-dzk-8 小时前
【贪心算法】LC 121.买卖股票的最佳时机
算法·贪心算法
A_nanda8 小时前
c#WPF开发常见问题
开发语言·c#·wpf
hanlin038 小时前
动态规划专练:力扣第718、1143题
算法·leetcode·动态规划
ChaoZiLL8 小时前
二叉树经典例题
数据结构·算法
Hello.Reader9 小时前
REALITY 技术深度解析从 TLS 伪装、抗主动探测到 VLESS + XTLS Vision 完整实践
开发语言·php