背景

构造线程之后抛出异常,如果对象仍持有 joinable 的 std::thread,退出路径可能直接终止程序。线程拥有关系需要覆盖异常。

核心判断

  1. C++20 可用 jthread 表达请求停止与等待的拥有关系。
  2. 工作循环检查 stop_token,阻塞操作也要有可唤醒路径。
  3. 析构顺序保证线程先退出,再销毁它引用的资源。

最小示例

下面保留核心逻辑;业务类型、调用入口和环境配置按项目补齐。

std::jthread worker([](std::stop_token stop) { while (!stop.stop_requested()) do_one_iteration(); });

边界与误区

jthread 的析构会请求停止并等待,但不会神奇打断任意阻塞 I/O。持锁等待线程结束也可能形成死锁。

验证方式

测试异常退出、空闲阻塞和执行中停止,记录析构等待时间;故意调整成员析构顺序,确认被访问资源不会先于线程销毁。

小结

线程拥有者必须负责 join 或请求停止,异常路径不能留下 joinable 线程。