C++多线程单队列线程池

//原文:http://purecpp.org/detail?id=2260
 线程池(大小型 线程号=线程::硬件并行());
< F,...A>
 入列(F&&f,A&&...a);
//入列,返回未来.可满足`激进`取`异步执行`结果.

未来<调果型<F,A...>>
//如上为R,可`空`.
 线程池{
:
   线程池(大小型 线程=线程::硬件并行());
  < F,...A> 入列(F&&f,A&&...a);
  ~线程池();

:
  向量<线程>工作者;
  //线程组
  队列<函数<()>>任务;
  //队列,多线程从队列中`抢任务模式`
  互斥锁 队列互斥锁;
  条件变量 条件;
  //用来实现`通知`机制
   停止;//停止并清理任务和线程
  //用变量,因为线程池与应用生命期一般一样
};//声明

内联 线程池::线程池(大小型 线程):停止(){
  (大小型 i=0;i<线程;++i)
    工作者.原后([]{
      (;;){
        函数<()>任务;
        {
          独锁<互斥锁>(->队列互斥锁);
          ->条件.等待(,[]{ ->停止||!->任务.空的();});//等待两个条件
          //后面条件是`直到`,停止或非空则不等待了.
          (->停止&&->任务.空的())
            ;//返回
          任务=移动(->任务.());
          ->任务.();
        }//注意加锁范围,取出任务后,就解锁

        任务();//有任务时,唤醒,并执行
      }
    });
}

< F,...A>
 线程池::入列(F&&f,A&&...a){
   R=调果型<F,A...>;
   任务=造共<打包任务<R()>>(
      绑定(前向<F>(f),前向<A>(a)...));
  //任务包,取未来
  未来<R>资源=任务->取未来();
  {
    独锁<互斥锁>(队列互斥锁);
    (停止)
       运行时错误("已停止,不能入列");
    任务.原位([任务=移动(任务)]{(*任务)();});
  }//加锁范围.入列后,就可解锁了.
  条件.通知一个();//多线程抢一个,通知所有无意义
   资源;
}
内联 线程池::~线程池(){
  {
    独锁<互斥锁>(队列互斥锁);
    停止=;
  }
  条件.通知所有();//停止所有线程
  (线程&工作者:工作者)
    工作者.合并();
}//唤醒后,取出任务并执行,队列为空时,才退出.
//测试代码
#包含<io流>
#包含"简单线程池.h"

 测试简单池(){
    线程池 池;.入列([]{输出<<"你好\n";});
     未来=.入列([]( ){"你好"+;},"世界");
    输出<<未来.()<<'\n';
}

//条件变量,两个`等待`接口,有`判定`与无判定,`无判定`的要注意`假唤醒`,要这样写:
(!停止)等待();
//wait(lock, stop)这样就可以,内部也是上面循环
posted @   zjh6  阅读(16)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示