新闻中心

c++中如何实现一个线程池_线程池原理与C++实现示例讲解

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

c++中如何实现一个线程池_线程池原理与c++实现示例讲解

线程池的核心思想是提前创建一批线程,避免频繁创建和销毁线程带来的开销。任务提交后由空闲线程处理,提升程序并发性能。C++中可通过标准库的 std::threadstd::queuestd::mutexstd::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>> {
    using 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 Musho

AI网页设计Figma插件

Musho 76 查看详情 Musho

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式管理  百度网盘网页版入口 百度网盘网页版官方登录网址 

搜索