C++11 线程池

C++11实现线程池

根据网友提出的思路略有改动-----已测试

#pragma once
#include<iostream>
#include<thread>
#include<list>
#include<algorithm>
#include<functional>
#include<typeinfo>
#include<mutex>
#include<future>
#include<atomic>
#include<condition_variable>
#include<memory>

//线程池
class ThreadPool
{
private:
	//定义一个无参无返回值的function类型,此类型将用做任务的存储类型,所有传入的函数都将转换为此类型
	using Task = std::function<void()>;
	//最大线程数,根据需要在构造函数中设置,过大会引起上下文频繁切换
	int threadNum;
	//剩余可用线程数
	std::atomic<int> usableThread;		
	//存放线程的容器
	std::list<std::thread> pools;
	//存放转换后的任务
	std::list<Task> tasks;
	//互斥量
	std::mutex mu;
	//阻塞条件
	std::condition_variable cond;
	//所有线程是否继续执行
	std::atomic<bool> running;
public:
	//线程池构造函数,maxThreadNum为最大线程数
	ThreadPool(int maxThreadNum = 6):threadNum(maxThreadNum),usableThread(maxThreadNum)
	{
		running.store(true);
		//创建线程
		for (int i = 0; i < maxThreadNum; i++)
		{
			//创建线程,循环等待任务的执行
			std::thread t([this]() 
				{
					Task nowtask;//当前要执行的任务
					//不断获取任务,不断执行
					while (running.load())
					{
						//从任务容器中获取任务,如果没有任务则阻塞
						{
							std::unique_lock<std::mutex> locker(mu);
							//等待,一直到有任务时
							while (this->tasks.empty()&&running.load())
							{
								cond.wait(locker);
							}
							if (this->tasks.empty())//如果是running关闭
							{
								continue;
							}
							//取出任务
							nowtask = std::move(this->tasks.front());
							this->tasks.pop_front();
						}
						usableThread--;
						nowtask();
						usableThread++;
					}
				});
			//把创建的线程放到线程池中 ,线程对象没有复制构造函数,只有移动构造函数
			pools.emplace_back(std::move(t));
		}
	}
	//析构函数
	~ThreadPool()
	{
		running.store(false);
		cond.notify_all();
		//将所有线程资源释放
		for (std::thread& th : pools)
		{
			if (th.joinable())
			{
				th.join();
			}
		}
	}

	//将传进来的函数转换为统一类型的函数
	template<typename F,typename ... Args>
	auto commit(F&& f, Args&& ...args)->std::future<decltype(f(args...))>
	{
		//获取传入函数的返回值类型
		using RetType = decltype(f(args...));
		//获取指向std::packaged_task<RetType()>的智能指针
		std::shared_ptr<std::packaged_task<RetType( )> > task = 
			std::make_shared<std::packaged_task<RetType( )>>
			(
				std::bind(std::forward<F>(f), std::forward<Args>(args)...)
			);
		//获取智能指针task所指向packaged_task的future
		std::future<RetType> future = task->get_future();
		{
			std::unique_lock<std::mutex> locker(mu);
			//将一个无参,无返回值的函数放入任务队列中
			tasks.emplace_back([task]() {(*task)(); });
		}
		cond.notify_one();
		return future;
	}
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值