C++实现线程池

CThreadPool.h

#pragma once

#include <functional>
#include <future>
#include <iostream>
#include <queue>
#include <vector>
#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>

class CThreadPool
{
	using Task = std::function<void()>;

public:
	CThreadPool(size_t size);
	~CThreadPool();

	// 添加任务
	template <typename F, typename ...Args>
	auto mAddTask(F&& f, Args && ...args) -> std::future<decltype(f(args...))>;

	// 线程工作函数
	void mWork();

private:
	std::vector<std::thread> mThreadPools;   // 线程池
	std::queue<Task>         mTasks;         // 任务
	std::mutex               mLock;          // 锁
	std::condition_variable  mCVTask;        // 条件变量
	std::atomic<bool>        mExit;          // 退出标志
};

// 测试函数
void test();

CThreadPool.cpp

#include "CThreadPool.h"

CThreadPool::CThreadPool(size_t size) : mExit(false)
{
	size = (size <= 0) ? 1 : size;
	for (size_t i = 0; i < size; ++i) {
		mThreadPools.emplace_back(std::move(std::thread(&CThreadPool::mWork, this)));
	}
}

CThreadPool::~CThreadPool()
{
	// 退出标志
	mExit.store(true);

	// 告知等待的线程,退出wait
	mCVTask.notify_all();

	// 
	for (std::thread& thread : mThreadPools) {
		thread.join();      // 等待线程结束任务(需要mExit)
		// thread.detach(); // 让线程自生自灭  (不需要mExit)
	}
}

// 添加任务
template <typename F, typename ...Args>
auto CThreadPool::mAddTask(F&& f, Args && ...args) -> std::future<decltype(f(args...))>
{
	// 获取函数的返回值类型
	using ret_type = decltype(f(args...));
	// 等价于: using ret_type = typename std::result_of<F(Args...)>::type;

	// 将执行构造成智能指针
	auto task_func = std::make_shared<std::packaged_task<ret_type()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));

	// 添加任务到队列
	{
		std::unique_lock<std::mutex> uq_lock(mLock);
		mTasks.emplace([task_func]() { (*task_func)(); }); // 构造lambda表达式,调用std::package_task的operaor()
	}

	// 唤醒线程
	mCVTask.notify_one();

	// 返回
	return task_func->get_future();
}

// 线程工作函数
void CThreadPool::mWork()
{
	while (1) {
		// 等待被唤醒
		std::unique_lock<std::mutex> uq_lock(mLock);
		mCVTask.wait(uq_lock, [this]() { return !mTasks.empty() || mExit.load();});

		// 如果线程池被销毁,则退出
		if (mExit.load()) {
			return;
		}

		// 取出任务
		Task task(std::move(mTasks.front()));
		mTasks.pop();
		
		// 执行任务
		task();
	}
}

int Task1(int) 
{
	std::cout << "Thread ID : " << std::this_thread::get_id() << ", Task1 start..." << std::endl;
	std::this_thread::sleep_for(std::chrono::seconds(1)); // 1s
	std::cout << "Thread ID : " << std::this_thread::get_id() << ", Task1 end..." << std::endl;
	return 24;
}

class Task2 
{
public:
	int operator()(int, int) {
		std::cout << "Thread ID : " << std::this_thread::get_id() << ", Task2 start..." << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(2)); // 2s
		std::cout << "Thread ID : " << std::this_thread::get_id() << ", Task2 end..." << std::endl;

		return 24;
	}
};

void test()
{
	std::cout << "Main Thread ID : " << std::this_thread::get_id() << ", start..." << std::endl;

	// 创建线程池
	CThreadPool thread_pool(5);

	// 添加任务
	std::future<int> f_task1 = thread_pool.mAddTask(Task1, 1);
	std::future<int> f_task2 = thread_pool.mAddTask(Task2(), 1, 1);
	std::future<int> f_task3 = thread_pool.mAddTask([]() {
		std::cout << "Thread ID : " << std::this_thread::get_id() << ", Task3 start..." << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(3)); // 3s
		std::cout << "Thread ID : " << std::this_thread::get_id() << ", Task3 end..." << std::endl;
		return 8; 
	});

	// 任务返回的结果
	std::cout << "Task1 return value : " << f_task1.get() << std::endl;
	std::cout << "Task2 return value : " << f_task2.get() << std::endl;
	std::cout << "Task3 return value : " << f_task3.get() << std::endl;

	std::cout << "Main Thread ID : " << std::this_thread::get_id() << ", end..." << std::endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值