新闻中心

c++中如何实现一个简单的线程池_c++线程池实现思路与示例

2025-11-01
浏览次数:
返回列表
答案:C++线程池通过预创建线程、任务队列和同步机制实现高效任务调度,核心包括线程组、std::queue存储任务、std::mutex与condition_variable保障线程安全,支持RAII管理资源,可复用线程避免频繁创建开销。

c++中如何实现一个简单的线程池_c++线程池实现思路与示例

在C++中实现一个简单的线程池,核心思路是预先创建一组工作线程,通过任务队列接收外部提交的任务,由空闲线程自动从队列中取出并执行。这种方式避免了频繁创建和销毁线程的开销,提高程序性能。

线程池的基本组成

一个基本的线程池通常包含以下几个部分:

  • 线程组: 一组等待任务的工作线程。
  • 任务队列: 存放待执行任务的容器,通常使用队列结构(如std::queue)。
  • 互斥锁与条件变量: 保护任务队列的线程安全,并实现线程间的同步唤醒。
  • 控制开关: 标记线程池是否运行,用于优雅关闭。

任务的定义与存储

任务一般以可调用对象的形式存在,比如函数、lambda表达式或函数对象。可以使用std::function统一包装这些类型。

示例:

#include <functional>
#include <queue>

using Task = std::function<void()>;
std::queue<Task> tasks_;

这样就可以把不同形式的任务都存入同一个队列中。

线程同步机制

多个线程访问共享任务队列时必须加锁。使用std::mutex保护队列,再配合std::condition_variable实现“有任务就通知线程”的机制。

短影AI 短影AI

长视频一键生成精彩短视频

短影AI 170 查看详情 短影AI

关键代码片段:

std::mutex mtx_;
std::condition_variable cv_;
bool stop_ = false;

// 添加任务
void enqueue(Task task) {
    std::unique_lock<std::mutex> lock(mtx_);
    tasks_.push(std::move(task));
    cv_.notify_one(); // 唤醒一个线程
}

// 工作线程循环
void worker() {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx_);
        cv_.wait(lock, [this] { return !tasks_.empty() || stop_; });
        
        if (stop_ && tasks_.empty()) break;

        Task task = std::move(tasks_.front());
        tasks_.pop();
        lock.unlock();

        task(); // 执行任务
    }
}

线程池类的简单实现

将上述组件整合成一个完整的类:

#include <iostream>
#include <vector>
#include <thread>
#include <queue>
#include <functional>
#include <mutex>
#include <condition_variable>

class ThreadPool {
public:
    explicit ThreadPool(size_t threads) : stop_(false) {
        for (size_t i = 0; i < threads; ++i) {
            workers_.emplace_back([this] {
                worker();
            });
        }
    }

    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(mtx_);
            stop_ = true;
        }
        cv_.notify_all();
        for (auto& t : workers_) {
            t.join();
        }
    }

    void enqueue(Task task) {
        std::unique_lock<std::mutex> lock(mtx_);
        tasks_.push(std::move(task));
        cv_.notify_one();
    }

private:
    using Task = std::function<void()>;
    std::vector<std::thread> workers_;
    std::queue<Task> tasks_;
    std::mutex mtx_;
    std::condition_variable cv_;
    bool stop_;

    void worker() {
        while (true) {
            std::unique_lock<std::mutex> lock(mtx_);
            cv_.wait(lock, [this] { return !tasks_.empty() || stop_; });
            if (stop_ && tasks_.empty()) return;
            Task task = std::move(tasks_.front());
            tasks_.pop();
            lock.unlock();
            task();
        }
    }
};

使用示例

提交一些简单任务测试线程池:

int main() {
    ThreadPool pool(4); // 创建4个线程

    for (int i = 0; i < 8; ++i) {
        pool.enqueue([i] {
            std::cout << "任务 " << i << " 正在执行,线程ID: "
                      << std::this_thread::get_id() << '\n';
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        });
    }

    // 主函数退出前,pool析构会等待所有任务完成
    return 0;
}

这段代码会看到8个任务被4个线程并发处理,输出顺序不固定但总能完成。

基本上就这些。这个线程池虽然简单,但具备了核心功能:复用线程、安全添加任务、自动调度执行、支持RAII资源管理。进一步可以扩展支持返回值(结合std::future)、动态调整线程数等,但对大多数场景来说,这个版本已经够用。

以上就是c++++中如何实现一个简单的线程池_c++线程池实现思路与示例的详细内容,更多请关注其它相关文章!


# 相关文章  # 舟山营销推广平台电话地址  # 查询seo排名  # 浙江祥云平台网站建设  # 新网站优化简历模板范文  # 营销推广公司有哪几家  # 传奇短信营销推广  # seo优化网站如何布局  # 盐城机械网站建设  # 鹰潭网站营销推广哪个好  # 海东地区网站优化外包  # 解决问题  # 中文网  # ai  # 这段  # 多个  # 几个  # 边缘  # 复用  # 如何实现  # 游戏开发  # 同步机制  # stream  # ios  # c++ 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 腾讯视频怎么使用多账号家庭管理_腾讯视频家庭多账号统一管理与权限分配教程  解决Bootstrap卡片顶部边距导致背景图下移的问题  汽水音乐车机版横屏版7.1 汽水音乐车机版横屏版下载入口  支付宝碰一碰设备是REDMI手机吗 博主拆机辟谣:处理器、内存都不一样  C++ explicit关键字防止隐式转换_C++构造函数安全规范  12306怎么选座位选到安静区_12306选座安静区域选择策略  Yandex免登录网页版地址 Yandex搜索引擎官方访问入口  可靠CSGO开箱平台解析 CSGO开箱网合集  优化 Python 函数中的条件逻辑:解决 if-else 嵌套与参数选择问题  在Go语言中利用后缀数组处理多字符串:实现高效文本匹配与自动补全  铃兰之剑为这和平的世界希里技能组及加点推荐  《北京人工智能产业白皮书(2025)》发布:全年核心产值预计突破 4500 亿元  解决 Express.js 中 PUT 请求密码修改失败的路由配置指南  AO3同人作品网入口 AO3搜索引擎官网永久地址  QQ邮箱登录平台入口 QQ邮箱网页版邮箱官方入口  Django模型中自动计算可用余额的实现方法  J*aScript中高效管理与清空动态列表:避免循环陷阱  windows10怎么查看本机ip_windows10命令提示符ipconfig使用  win11 arm版怎么安装 M1/M2 Mac虚拟机安装ARM win11的方法  离线运行Go语言之旅:本地部署与GOPATH配置指南  BetterDiscord插件中安全更新用户简介的实践指南  html5 app怎么运行环境_配html5 app运行环境【教程】  网易大神怎么保存别人动态的图片_网易大神动态图片保存方法  b站怎么取消点赞_b站点赞取消操作方法  漫蛙2在线漫画入口 漫蛙正版漫画网页版直达  c++ dfs和bfs代码 c++深度广度优先搜索算法  Node.js CSV 数据处理:基于字段空值条件过滤整条记录的策略  uc手机浏览器网页版入口 uc浏览器手机版便捷登录首页  Yandex搜索引擎一键访问入口_俄罗斯Yandex官网免登录  yy漫画网页版官方入口_yy漫画官网登录页面链接  蛙漫漫画官网在线入口 蛙漫全本漫画免费阅读平台  b站怎么删除评论_b站评论管理与删除操作  Win10如何开启蓝牙功能_Windows10找不到蓝牙开关解决方法  Composer如何在生产环境安全地执行composer update  冬*霸灯泡不亮怎么办_浴霸取暖灯一盏不亮的灯座清洁修复法  在React函数组件中利用原生HTML5进行邮箱地址验证  天眼查企业查询官网入口 天眼查官方网页版查询  如何在 Windows 11 中启动游戏手柄设置  提升Kafka消费者健壮性:会话超时处理与消息处理语义  J*aScriptWebpack优化_J*aScript构建工具实战  如何在J*a中实现统一对象行为接口_项目大型化时的接口规范化  小米Civi 4录制视频过暗_小米Civi 4亮度优化  Steam官网入口直达 Steam注册及登录步骤  印象笔记如何设离线包出差查阅_印象笔记设离线包出差查阅【离线阅读】  怎样在Excel中做仪表盘_Excel仪表盘设计与关键指标展示方法  谷歌邮箱注册显示错误Gmail服务器异常与延迟处理  一加Ace 6T支持全新明眸护眼:通过了最严苛的护眼小金标认证  2025俄罗斯Yandex最新入口 官方网站地址及浏览器下载指南  深入理解Google Cloud Datastore查询:祖先路径与数据一致性  J*aScript中向JSON对象添加新属性的正确姿势 

搜索