第十九课:C++多线程的线程池简单实现

/*
线程池:
有限个创建好的线程,开始时是空闲的,
当有任务需要线程处理,从空闲线程中取出线程去处理,
处理好后,放回原线程队列中。(线程容器:具有派发和回收线程功能)

设计线程池的关键问题:
->可使用的线程数量
->高效的分配任务的方式
->如何等待任务完成

需要知识功底:
1,数据结构队列;
2,c++泛型编程;
3,函数包装器;
4,函数适配器;
5,异步线程
6,智能指针
*/

#include<iostream>
#include<queue>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<functional>
#include<future>
#include<exception>

using namespace std;
using namespace this_thread;

class ThreadPool
{
public:

	ThreadPool(size_t size);
	~ThreadPool();
	template<class F,class...Args>                                      
	auto enqueue(F&& f, Args&&...args) -> future<decltype(f(args...))>;  //入队、检测类型

protected:
	
	queue<function<void()>> tasks;   //任务列表
	vector<thread> workers;          //工作线程

	mutex queue_mutxex;              //互斥量
	condition_variable condition;    //条件变量
	bool stop;                       //停止开关          

};


int func(int i)
{
	printf("线程在干活:%d\n",i);

	this_thread::sleep_for(1s);

	printf("线程结束:%d\n", i);

	return i * i;
}



int main()
{
	ThreadPool pool(4);

	vector<future<int>> results;

	for (int i = 0; i < 8; i++)
	{
		results.emplace_back(pool.enqueue(func,i));
	}

	for (auto& v : results)
	{
		printf("结果:%d\n",v.get());
	}


	return 0;
}

ThreadPool::ThreadPool(size_t size):stop(false)
{
	for (int i = 0; i < size; i++)
	{
		workers.emplace_back(

			[this]
			{
				while (true)
				{
					function<void()> task;
					{
			unique_lock<mutex> locks(this->queue_mutxex);
			this->condition.wait(locks, [this] {return this->stop || !this->tasks.empty(); });
						if (this->stop && this->tasks.empty())
						{
							return;
						}
						task = move(this->tasks.front());
						this->tasks.pop();
					}
					task();
				}
			}

		);
	}

}

ThreadPool::~ThreadPool()
{
	{
		unique_lock<mutex> lock(queue_mutxex);

		stop = true;

	}

	condition.notify_all();

	for (auto& t : workers)
	{
		t.join();
	}
}

template<class F, class ...Args> 

auto ThreadPool::enqueue(F&& f, Args && ...args) -> future<decltype(f(args...))>
{

	using Type = decltype(f(args...));

	auto task = make_shared<packaged_task<Type()>>(bind(forward<F>(f), forward<Args>(args)...));

	future<Type> res = task->get_future();

	{
		unique_lock<mutex> lock(queue_mutxex);

		if (stop)
		{
			throw runtime_error("当前没有空闲线程!");
		}

		tasks.emplace([task] {(*task)(); });
	}

	condition.notify_one();

	return res;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值