简单的c++线程池实现

ThreadPool 代码介绍

该代码实现了一个简单的 C++ 线程池(ThreadPool),用于管理并发执行的任务。

头文件

#include <queue>
#include <mutex>
#include <future>
#include <iostream>
#include <condition_variable>
using namespace std;

std::mutex mtx;

class ThreadPool {
public:
    ThreadPool(int thread_num = THREAD_MAX);
    
    template <typename function, typename... args>
    void addtask(function&& fnc, args&&... arg);
    
    ~ThreadPool();

private:
    bool stop;
    std::vector<std::thread> threads;
    std::queue<std::function<void()>> tasks;
    std::mutex queuemutex;
    std::condition_variable condition;
}; 

void task(int id);

构造函数

构造函数 ThreadPool::ThreadPool(int thread_num) 接收一个可选的线程数参数 thread_num,默认为 THREAD_MAX。在构造函数中,根据指定的线程数创建线程,并使用 lambda 表达式作为线程函数。每个线程会持续运行一个循环,等待任务队列中有可执行的任务,然后取出任务并执行。

ThreadPool::ThreadPool(int thread_num):stop(false)
{
	for (int i = 0; i < thread_num; i++)
	{
        threads.emplace_back([this] {while (true)
        {
            std::function<void()> task;
            std::unique_lock<std::mutex> lock(queuemutex);
            condition.wait(lock, [this] {return stop || !tasks.empty(); });
            if (stop && tasks.empty())
            {
                return;
            }
            task = std::move(tasks.front());
            tasks.pop();
            lock.unlock();
            task();
        }});

	}
}

添加任务

成员函数 ThreadPool::addtask 用于向线程池添加任务。它接收一个可调用对象 fnc 和可变参数 args...,通过使用 std::bindstd::forward 进行参数绑定和转发,创建一个 std::packaged_task 对象,并将其放入任务队列中。添加任务后,通过调用 condition.notify_one() 来通知一个等待中的线程有任务可执行。

void ThreadPool::addtask(function&&fnc, args&&...arg)
{
    auto task = std::make_shared<std::packaged_task<void()>>(std::bind(std::forward<function>(fnc), std::forward<args>(arg)...));
    std::unique_lock<std::mutex> lock(queuemutex);
    tasks.emplace([task]() { (*task)(); });
    lock.unlock();
    condition.notify_one();
}

析构函数

析构函数 ThreadPool::~ThreadPool() 负责线程池的清理工作。它首先将 stop 标志设置为 true,然后通过调用 condition.notify_all() 通知所有等待中的线程停止等待。接下来,使用循环等待所有线程执行完成,通过调用 thread.join() 加入主线程。

ThreadPool::~ThreadPool()
{
    std::unique_lock<std::mutex> lock(queuemutex);
    stop = true;
    condition.notify_all();
    for (std::thread& thread : threads)
    {
        thread.join();
    }
}

示例任务函数

函数 task 是一个示例任务函数,它接收一个整数参数 id,并在控制台输出任务的执行信息。

void task(int id) {
    
    std::unique_lock<std::mutex> lock(mtx);
    std::cout << "task " << id << " executed by thread " << std::this_thread::get_id() << std::endl;
    lock.unlock();
}

主函数

main 函数中,首先创建了一个 ThreadPool 对象 threadpool。然后使用一个循环向线程池添加 10 个任务,每个任务都是调用 task 函数,并传入不同的任务 ID。最后,通过 std::this_thread::sleep_for 函数使主线程休眠 2 秒,以等待所有任务执行完成。

int main() {
     /*创建线程池*/
    ThreadPool threadpool;

    for (int i = 0; i < 10; ++i) 
    {
        
        threadpool.addtask(task, i);
    }

  
    std::this_thread::sleep_for(std::chrono::seconds(2));

    return 0;
}

以上是对 ThreadPool 代码的详细介绍,,希望对您有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值