std::jthread 析构时自动 join(),无需手动调用;内置 stop_source 支持协作中断,通过 stop_token 通知线程主动退出;仅可移动不可复制;C++20 起支持,比 std::thread 稍大但无运行时开销。

std::jthread 构造后自动 join,不用手动调用
std::jthread 在析构时会自动调用 join(),这是它和 std::thread 最关键的区别。如果你习惯写 std::thread t{func}; t.join();,换成 std::jthread 后,只要不显式调用 detach(),对象离开作用域就安全等待完成。
常见错误现象:有人把 std::jthread 当成“带 join 的 std::thread”,却在析构前又手动调用 join(),结果二次 join 导致程序终止(std::thread::join() on a thread that is not joinable)。
- 构造即启动,无需额外 start 步骤
- 若需提前退出并放弃等待,调用
request_stop()+join()(见下节) - 如果确实想分离线程,必须显式调用
detach(),否则析构时强制join() - 不能复制,只能移动 —— 和
std::thread一致
如何配合 stop_token 实现可协作中断
std::jthread 内置 std::stop_source,可通过 get_stop_token() 获取 std::stop_token,让线程函数主动检查是否被请求停止。这比轮询全局 flag 更标准、更轻量。
使用场景:长时间运行的循环任务(如日志轮转、心跳发送、数据采集),需要响应外部关闭信号。
立即学习“C++免费学习笔记(深入)”;
- 线程函数第一个参数类型为
std::stop_token,编译器会自动传入 - 在循环中用
if (token.stop_requested()) break;检查 - 主线程调用
jthread.request_stop()发起请求,不会阻塞,也不保证立即生效 - 注意:
stop_token不提供同步语义,不要依赖它做临界区保护
示例:
std::jthread t{[](std::stop_token token) {
while (!token.stop_requested()) {
// 做点事...
std::this_thread::sleep_for(100ms);
}
}};
1 秒后请求停止:
t.request_stop(); // 不会等线程结束
std::jthread 与 std::thread 混用要注意什么
可以安全地把 std::jthread 移动给 std::thread 变量(因为 std::jthread 继承自 std::thread),但反过来不行。不过这种混用通常没意义,反而容易混淆生命周期管理逻辑。
性能 / 兼容性影响:
-
std::jthread对象比std::thread稍大(多一个stop_source成员),但无运行时开销 - C++20 起可用,MSVC 19.29+、GCC 10+、Clang 12+ 支持;老编译器无法降级使用
- 不能和
std::thread直接比较是否相等(operator==未定义),也不能用于std::vector<:jthread></:jthread>的 resize(因无默认构造) - 若要存多个可停止线程,推荐用
std::vector<:jthread></:jthread>并逐个构造,别用 push_back 默认构造再赋值
为什么有时候 request_stop() 像没起作用
最常见原因是线程函数没检查 stop_token,或者只在循环开头检查、但卡死在某个阻塞调用里(比如 std::condition_variable::wait)。
正确做法是:所有可能长期阻塞的系统调用,尽量用支持 stop_token 的重载版本。
-
std::condition_variable::wait(..., stop_token)会在收到 stop 请求时唤醒并返回false -
std::this_thread::sleep_until(..., stop_token)同理 - 原生系统调用(如
read(),epoll_wait())仍需自己封装检查逻辑 - 不要在析构函数或 signal handler 中调用
request_stop()——std::stop_source不是 async-signal-safe
真正复杂的地方在于:协作中断不是“立刻杀死线程”,而是“通知它该停了”;线程是否响应、何时响应、响应到哪一步,全由你写的逻辑决定。漏掉一次检查,就可能卡住整个 shutdown 流程。











