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;
}
相关推荐
倒头就睡的小比特5 天前
算法竞赛C++常用的STL
c++·算法
weilx12345 天前
C++笔记-文件IO-<fcntl.h>
c++
小羊没烦恼!5 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
伞伞悦读5 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
猎头南楼5 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
Smileyqp沛沛5 天前
前端?C++ ?较大差异基础罗列
c++·基础·前端转c++
C语言小火车5 天前
C/C++ 为什么需要编译器?
开发语言·c++
旖旎夜光5 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark5 天前
大规模并行计算中的负载均衡算法研究4
算法
吞下星星的少年·-·5 天前
C++ 萌新语法入门篇
c++·算法比赛