背景
构造线程之后抛出异常,如果对象仍持有 joinable 的 std::thread,退出路径可能直接终止程序。线程拥有关系需要覆盖异常。
核心判断
- C++20 可用 jthread 表达请求停止与等待的拥有关系。
- 工作循环检查 stop_token,阻塞操作也要有可唤醒路径。
- 析构顺序保证线程先退出,再销毁它引用的资源。
最小示例
下面保留核心逻辑;业务类型、调用入口和环境配置按项目补齐。
std::jthread worker([](std::stop_token stop) { while (!stop.stop_requested()) do_one_iteration(); });
边界与误区
jthread 的析构会请求停止并等待,但不会神奇打断任意阻塞 I/O。持锁等待线程结束也可能形成死锁。
验证方式
测试异常退出、空闲阻塞和执行中停止,记录析构等待时间;故意调整成员析构顺序,确认被访问资源不会先于线程销毁。
小结
线程拥有者必须负责 join 或请求停止,异常路径不能留下 joinable 线程。