新闻中心
c++中如何实现一个线程池_线程池原理与C++实现示例讲解
线程池通过预先创建线程并复用以减少开销,提升并发性能;C++中利用std::thread、std::queue、std::mutex和std::condition_variable可实现基本线程池,包含工作线程、任务队列、同步机制与生命周期管理;示例代码展示了一个支持返回值的线程池实现,构造时启动指定数量线程,任务通过enqueue提交并返回std::future,析构时自动回收资源;使用注意包括异常处理、动态调整线程数、无锁队列优化及空闲超时退出等。

线程池的核心思想是提前创建一批线程,避免频繁创建和销毁线程带来的开销。任务提交后由空闲线程处理,提升程序并发性能。C++中可通过标准库的 std::thread、std::queue、std::mutex 和 std::condition_variable 实现一个基础线程池。
线程池基本原理
线程池包含以下关键组件:
- 工作线程:固定数量的线程在后台等待任务。
- 任务队列:存放待执行的任务(通常为函数对象)。
- 同步机制:使用互斥锁保护共享数据,条件变量实现线程阻塞与唤醒。
- 生命周期管理:控制线程池启动、关闭和资源回收。
C++ 线程池实现示例
下面是一个简洁可运行的线程池实现:
#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <future>
<p>class ThreadPool {
public:
explicit ThreadPool(size_t numThreads) : stop(false) {
for (size_t i = 0; i < numThreads; ++i) {
workers.emplace_back([this] {
while (true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(queue_mutex);
condition.wait(lock, [this] { return stop || !tasks.empty(); });
if (stop && tasks.empty()) return;
task = std::move(tasks.front());
tasks.pop();
}
task();
}
});
}
}</p><pre class='brush:php;toolbar:false;'>template<class F>
auto enqueue(F&& f) -> std::future<typename std::invoke_result_t<F>> {
usin
g return_type = typename std::invoke_result_t<F>;
auto task = std::make_shared<std::packaged_task<return_type()>>(
std::forward<F>(f)
);
std::future<return_type> res = task->get_future();
{
std::unique_lock<std::mutex> lock(queue_mutex);
if (stop) throw std::runtime_error("enqueue on stopped ThreadPool");
tasks.emplace([task]() { (*task)(); });
}
condition.notify_one();
return res;
}
~ThreadPool() {
{
std::unique_lock<std::mutex> lock(queue_mutex);
stop = true;
}
condition.notify_all();
for (std::thread &worker : workers)
worker.join();
}private: std::vector<:thread> workers; std::queue<:function>> tasks;
std::mutex queue_mutex; std::condition_variable condition; bool stop;
};
使用示例
演示如何提交任务并获取返回值:
Musho
AI网页设计Figma插件
76
查看详情
int main() {
ThreadPool pool(4); // 创建4个线程的线程池
<pre class='brush:php;toolbar:false;'>std::vector<std::future<int>> results;
for (int i = 0; i < 8; ++i) {
results.emplace_back(
pool.enqueue([i] {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Task " << i << " running on thread "
<< std::this_thread::get_id() << '\n';
return i * i;
})
);
}
// 获取结果
for (auto& result : results) {
std::cout << "Result: " << result.get() << '\n';
}
return 0;}
该实现支持任意可调用对象,并通过 std::future 返回执行结果。构造时启动指定数量的工作线程,析构时自动等待所有任务完成并回收资源。
注意事项与优化方向
实际使用中需注意:
- 避免在任务中抛出未捕获异常,可能导致线程退出。
- 可根据负载动态调整线程数,而非固定大小。
- 高频率小任务场景下,可考虑无锁队列提升性能。
- 长时间空闲线程可设置超时退出,节省资源。
基本上就这些。这个线程池虽简单,但已具备核心功能,适合学习和中小型项目使用。
以上就是c++++中如何实现一个线程池_线程池原理与C++实现示例讲解的详细内容,更多请关注其它相关文章!
# 运算符
# 莱阳第三方推广营销公司
# 惊雷seo
# 昆明小程序网站建设
# 健身房营销推广效果
# 赞皇seo优化推广
# 医院网上建设网站
# 有关seo的论文题目
# 引流营销推广案例
# 深圳网站建设推广服务商
# 保山软文营销推广培训班
# 相关文章
# 长时间
# 换行符
# 是一个
# c++
# 返回值
# 如何选择
# 自定义
# 数据结构
# 如何实现
# red
# 标准库
# 同步机制
# 无锁
# stream
# ios
# ai
# 线程池
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
PDO预处理语句中冒号的正确处理:区分SQL函数格式与命名占位符
css卡片内容溢出如何处理_使用overflow隐藏或scroll显示内容
一加 Nord 5 隐私权限异常_一加 Nord 5 系统安全优化
J*aScript 字符串标签转换:使用正则表达式高效替换
QQ邮箱官方网站登录入口_QQ邮箱网页版在线使用
NetBeans Ant项目:自动化将资源文件复制到dist目录的教程
中兴BladeV30怎样用测距估书架层高_iPhone中兴BladeV30测距估书架层高【家装参考】
如何将HTML表格多行数据保存到Google Sheet
sublime如何优雅地处理行尾空格_sublime自动清理多余空白字符配置
12306选座怎么选到临时改签座_12306改签选座策略与步骤
b站怎么看视频的弹幕数量_b站弹幕数量查看方法
整合Supabase认证与Django模型:跨模式迁移的解决方案
win11开机启动修复循环怎么办 Win11无法进入系统高级启动解决方法【修复】
J*aScript中高效管理与清空动态列表:避免循环陷阱
LINUX怎么设置定时任务_LINUX crontab配置教程
铁路12306卧铺选择攻略 铁路12306下铺座位预定技巧
Golang如何使用net/url解析URL_Golang URL解析与处理方法
C++如何连接MySQL数据库_C++使用Connector/C++操作MySQL数据库教程
如何在更新Composer依赖后自动运行测试_使用post-update-cmd钩子触发PHPUnit
Lar*el 8 多关键词数据库搜索优化实践
谷歌google账号怎么注册账号 谷歌账号注册官方流程
PHP中高效并行检查多链接状态的教程
mc.js官网登录入口 mc.js官方登录入口最新版
c++如何实现单例设计模式_c++线程安全的单例模式写法
PySpark中从现有列右侧提取可变长度字符创建新列的教程
必由学官方网站入口 必由学学生教师共用登录通道
PS5 Pro有点优势但不多! 《燕云十六声》PS5平台与PC性能画面对比
抖音创作助手登录入口_抖音创作辅助工具官网直达
J*a里如何使用forEach遍历Map_Map遍历方法说明
J*a TimerTask文件监控:HashMap状态管理与常见陷阱规避指南
搜狗浏览器如何使用密码生成器创建强密码 搜狗浏览器内置密码安全工具
jQuery Mask 插件中实现电话号码固定前导零的教程
Composer的 archive 命令怎么用_快速打包你的PHP项目及其Composer依赖
C++如何实现异步操作_C++11使用std::future和std::async进行异步编程
文本文档写html代码怎么运行_文本文档html代码运行步骤【教程】
vivo浏览器自带的下载器速度慢怎么办 vivo浏览器提升文件下载速度的技巧
德邦快递查询平台 德邦快递物流信息查询入口
服务端验证_j*ascript输入检查
Golang如何优化CPU绑定任务分配策略_Golang CPU任务分配优化实践
excel怎么制作工资条 excel快速生成工资条的方法
漫画星球免费下拉式入口 漫画星球免费漫画在线阅读网站
Angular响应式表单:实现提交后表单及按钮的禁用与只读化
html两个JS只运行一个怎么办_让双JS在html中都运行方法【技巧】
163邮箱官方主页登录 直达网易邮箱登录核心页面
Surface怎么安装系统 微软Surface Pro U盘重装win11教程
在Socket.IO连接中实现Access Token自动更新与动态重连
HTML转PPT成品工具有哪些?HTML网页转PPT成品工具大全
C#如何安全地从用户上传的XML文件中读取数据? 验证与清理策略
c++20的std::jthread是什么_c++可中断线程与RAII式管理
百度网盘网页版入口 百度网盘网页版官方登录网址


2025-10-28
浏览次数:次
返回列表
g return_type = typename std::invoke_result_t<F>;
auto task = std::make_shared<std::packaged_task<return_type()>>(
std::forward<F>(f)
);
std::future<return_type> res = task->get_future();
{
std::unique_lock<std::mutex> lock(queue_mutex);
if (stop) throw std::runtime_error("enqueue on stopped ThreadPool");
tasks.emplace([task]() { (*task)(); });
}
condition.notify_one();
return res;
}
~ThreadPool() {
{
std::unique_lock<std::mutex> lock(queue_mutex);
stop = true;
}
condition.notify_all();
for (std::thread &worker : workers)
worker.join();
}