线程池是指定线程创建的个数,每个线程只是创建销毁一次。比起毫无限制的创建线程销毁线程效率更高。毕竟频繁的创建销毁线程会消耗系统资源,而且系统创建线程也是有上限的。
基于上一篇的线程安全队列实现
class thread_pool
{
private:
atomic_bool done; //原子操作
vector<thread> work_thread;//工作线程
thread_safe_queue<function<void()>> work_queue; //工作队列
public:
thread_pool(int n);
void submit(function<void()> f);
~thread_pool();
};
thread_pool::thread_pool(int n):done(false)
{
for(int i=0;i<n;i++)
{
work_thread.emplace_back([this](){
for(;;)
{
function<void()> task;
bool bl=this->work_queue.wait_and_pop(task,this->done);
if(bl)
{
//执行任务
task();
}
else
{
//进程结束条件
return ;
}
}
});
}
}
//1 notify_all非常重要,每个任务都notify_one,最终condition_variable.wait会被阻塞。使用notify_all
// 所有的进程都会出发一次wait,故而跳出阻塞,结束线程
thread_pool::~thread_pool()
{
done=true;
work_queue.notify_all();//1
for(auto &worker:work_thread)
{
worker.join();
}
}
void thread_pool::submit(function<void()> f)
{
work_queue.push(f);
}
int main()
{
thread_pool tp(20);
for(int i=0;i<20;i++)
{
tp.submit([i](){
this_thread::sleep_for(std::chrono::seconds(1));
cout<<i;
});
}
}
condition_variable:
是c++11多线程编程中提供的一种同步的机制。成员函数notify_one会通知一个等待线程,而成员函数notify_all会通知所有的等待线程。成员函数wait需要传递两个参数,一个锁一个函数指针。wait()会去检查函数的返回值。如果条件不满足(函数返回false),wait()函数会解锁互斥量,而且将这个线程置于阻塞或等待状态。当准备数据的线程调用notify_one()通知条件变量时,处理数据的线程从睡眠状态中苏醒,重新获得互斥锁,并且对条件再次判断,如果条件满足,从wait()返回并继续持有锁。如果条件不满足时,线程将对传入进来的互斥量解锁,并且重新开始等待。