当前位置: 首页 > news >正文

C++ 中 std::thread 的高级应用

C++ 中 std::thread 的高级应用、常见坑,以及如何封装为类,适合做线程池、异步任务、后台 worker、并发调度等场景。内容结构如下:


一、std::thread 高级用法清单

1. 线程成员函数调用(this 捕获)

class Worker {
public:void run() {std::thread t(&Worker::doWork, this); // 必须传 this 指针t.detach();}void doWork() {std::cout << "Running in thread: " << std::this_thread::get_id() << std::endl;}
};

2. 使用 Lambda 或函数对象启动线程

std::thread t([] {std::cout << "Lambda in thread\n";
});
t.join();

二、注意事项 & 常见坑

⚠️ 问题原因
std::terminate() 崩溃线程创建后未 join 或 detach
传引用未用 std::ref参数拷贝错误或未生效
多线程访问共享变量没加锁或未使用原子操作
类内线程管理失控析构时线程未清理,资源泄漏或崩溃

三、封装线程为类成员的完整模板

#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>class ThreadWorker {
public:ThreadWorker() : m_running(false) {}~ThreadWorker() {stop(); // 析构时停止线程}void start() {m_running = true;m_thread = std::thread(&ThreadWorker::threadFunc, this);}void stop() {if (m_running) {m_running = false;if (m_thread.joinable()) {m_thread.join();}}}private:void threadFunc() {while (m_running) {std::cout << "[Thread] Working... " << std::this_thread::get_id() << std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(500));}std::cout << "[Thread] Exiting." << std::endl;}std::thread m_thread;std::atomic<bool> m_running;
};

使用方法:

int main() {ThreadWorker worker;worker.start();std::this_thread::sleep_for(std::chrono::seconds(2));worker.stop();
}

四、进阶封装建议(适合线程池设计)

1. 使用 std::function<void()> 注册任意任务

std::function<void()> task = [] { std::cout << "Job\n"; };

2. 使用 std::queue + mutex + condition_variable 管理任务队列


五、其他高级工具组合推荐

工具用途
std::future, std::promise任务结果异步获取
std::packaged_task把函数打包为可异步执行任务
std::atomic原子变量,轻量线程同步
condition_variable多线程通信唤醒机制

总结建议

  • ✅ 线程内部用 std::atomic<bool> 控制退出比 bool 更安全
  • ✅ 类内线程要在析构时妥善停止并 join
  • ✅ 避免裸线程泄露:用类、封装、RAII 管理生命周期
  • ✅ 封装成线程池/任务队列是多线程项目的基础

相关文章:

  • 一篇文章学会开发第一个ASP.NET网页
  • leetcode刷题——判断对称二叉树(C语言版)
  • 若依项目部署小结
  • 【KWDB 创作者计划】_上位机知识篇---MQTT协议
  • Java单例模式详解:实现线程安全的全局访问点
  • Spring Security:企业级安全架构的设计哲学与工程实践
  • 块压缩[比如etc] vs 传统图片压缩 优缺点对比
  • 【KWDB 创作者计划】_深度学习篇---向量指令集
  • 使用rclone迁移minio文件
  • Kubelet 可观测性最佳实践
  • 【C/C++】插件机制:基于工厂函数的动态插件加载
  • 2025年渗透测试面试题总结-拷打题库13(题目+回答)
  • 【redis】主从复制
  • 程序员学英文之Shipment Claim 运输和索赔
  • Node.js学习
  • Vite/Rollup 模块热更新
  • Python内置函数---bytes()
  • MySQL基础增删改
  • CDN加速http请求
  • 百万点数组下memset、memcpy与for循环效率对比及原理分析
  • 限制再放宽!新版市场准入负面清单缩减到106项
  • 股市劝服马斯克
  • 金融监管总局:支持将上海打造成具有国际竞争力的再保险中心
  • 民生访谈|让餐饮店选址合规性可查、社区妙趣横生,上海有实招
  • 男粉丝咬伤女主播嘴后写的条子引争议:赔偿“十万元”还是“十5元”?
  • 亮相!神二十乘组与中外媒体记者集体见面