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;
}
相关推荐
apcipot_rain6 小时前
C++转Java日记(04)
java·开发语言·c++
NEFU_Jyj7 小时前
牛客周赛R168
算法
云和数据.ChenGuang8 小时前
LangGraph 异步 Node 的设计与写法实践
开发语言·人工智能·python·机器学习·php
WL学习笔记8 小时前
vector模拟实现
c++
蜗牛一步步往上爬11 小时前
第十六章 C++语言在深度学习中的应用
开发语言·c++·深度学习
张张123y13 小时前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent
Navigator_Z14 小时前
LeetCode //C - 1317. Convert Integer to the Sum of Two No-Zero Integers
c语言·算法·leetcode
wo_jack14 小时前
C++ 入门笔记(十六):第16课 vector 模拟实现十问十答 —— 从三指针到迭代器失效
c++·后端·面试·stl·vector
D e re k ZH15 小时前
C++ 标准库算法全景指南
数据结构·c++·算法