/*
线程池:
有限个创建好的线程,开始时是空闲的,
当有任务需要线程处理,从空闲线程中取出线程去处理,
处理好后,放回原线程队列中。(线程容器:具有派发和回收线程功能)
设计线程池的关键问题:
->可使用的线程数量
->高效的分配任务的方式
->如何等待任务完成
需要知识功底:
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;
}
第十九课:C++多线程的线程池简单实现
最新推荐文章于 2024-06-07 18:03:26 发布