c++如何实现线程池

  介绍

这篇文章主要为大家展示了c++如何实现线程池,内容简而易懂,希望大家可以学习一下,学习完之后肯定会有收获的,下面让小编带大家一起来看看吧。

最近自己写了一个线程池。

总的来说,线程池就是有一个任务队列,一个线程队列,线程队列不断地去取任务队列中的任务来执行,当任务队列中为空时,线程阻塞等待新的任务添加过来。

我是用队列来存放任务,向量存放线程*,然后用condition_variable来设置线程阻塞和唤醒。

下面直接上代码吧。

线程池类头文件Thread_Pool。h

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *   线程池头文件      作者:十面埋伏但莫慌   时间:2020/05/03      * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */# pragma>/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *   线程池CPP文件      作者:十面埋伏但莫慌   时间:2020/05/03      * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */# include" Thread_Pool.h"   # include   int任务::推动(函数Func) {   std:: unique_lock锁(mx);   尝试{   tasks.emplace(函数);   }   抓住(std::异常e)   {   把e;   返回1;   }   返回0;   }   int任务::getTaskNum ()   {   返回tasks.size ();   }   函数的任务:pop () {   std:: unique_lock锁(mx);   Func温度;   如果(tasks.empty ())   返回临时;   其他的   {   temp=tasks.front ();   tasks.pop ();   返回临时;   }   }   int Thread_Pool:: addtask(函数Func)   {      int ret=tasks.push(函数);   cond.notify_one ();   返回受潮湿腐烂;   }   空白Thread_Pool: start () {   如果(! IsStart) {   IsStart=true;   for (int i=0;我& lt;maxThreadNum;我+ +)   {   线程。emplace_back(新std::线程(std::绑定(及Thread_Pool::运行,这)));   }      }   }   空白Thread_Pool: run ()   {   而(IsStart)   {   函数f;   如果(tasks.getTaskNum ()==0,,IsStart)   {   std:: unique_lock锁(tasks.mx);   cond.wait(锁);   }   如果(tasks.getTaskNum () !=0,,IsStart)   {   f=tasks.pop ();   如果(f)   f ();   }      }   }   int Thread_Pool: getTaskNum () {   返回tasks.getTaskNum ();   }   空白Thread_Pool:停止(){      IsStart=false;   cond.notify_all ();   (自动T:线程){   std:: cout & lt; & lt;“线程“;& lt; & lt;T→get_id () & lt; & lt;“;已停止!”& lt; & lt;std:: endl;   T→加入();   如果(T !=nullptr)   {   删除T;   T=nullptr;   }   }   std:: cout & lt; & lt;“所有线程已停止!”& lt; & lt;std:: endl;   }   Thread_Pool:: ~ Thread_Pool () {   如果(IsStart)   {   停止();   }   }

最后是测试用的主。cpp

# include   # include" Thread_Pool.h"   使用名称空间性病;   空白string_out_one () {   cout & lt; & lt;“一个!“& lt; & lt;endl;   }   空白string_out_two () {   cout & lt; & lt;“两个!“& lt; & lt;endl;   }   空白string_out_three () {   cout & lt; & lt;“三!”& lt; & lt;endl;   }   int main () {   {   Thread_Pool池;   尝试{   Pool.start ();   }   抓住(std::异常e)   {   把e;   cout & lt; & lt;“线程池创建失败!”& lt; & lt;endl;   }   for (int i=0;我& lt;50000,)   {   如果(Pool.getTaskNum () & lt;1000){   Pool.addTasks (string_out_one);   Pool.addTasks (string_out_two);   Pool.addTasks (string_out_three);   std:: cout & lt; & lt;我+ + & lt; & lt;std:: endl;   }   }   获取字符();   }   获取字符();   返回0;   }

执行的效果如下:

 C + +如何实现线程池

线程唤醒和阻塞的逻辑就是在线程工作函数运行函数中,判断队列是否为空,若为空则设置锁并调用条件变量的等待函数,释放这个线程中的锁并阻塞线程,等待任务队列中新的任务添加进来后,

条件变量通过notify_one()随机唤醒一个在等待的线程,取出队列中的任务执行。

写这个线程池的过程中碰到的最主要需要注意的就是锁的使用,在对队列的写和释放时要注意加锁,在需要阻塞线程时,要注意通过{}设置锁的范围。

c++如何实现线程池