//原文: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)这样就可以,内部也是上面循环
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现