我们首先开门见山来介绍一下,在C++20 的 std::jthread具有两大特性:
自动合并 joining thread
线程取消 stop token
其中 jthread 的 "j" 指的就是 joining。
自动合并 joining thread
std::jthread 的第一个特点就是能够再析构函数中自动调用 join() 从而避免了无法合并的问题。

析构的变化:
其实具体实现的思路与上文中手动 diy 实现的类似。下面是 msvc 的源码。这里的操作比上文编写的多了一步,_Ssource.request_stop(); 请求停止。其余功能一致。
class {
// pass
~jthread() {
_Try_cancel_and_join();
}
void _Try_cancel_and_join() noexcept {
if (_Impl.joinable()) {
_Ssource.request_stop();
_Impl.join();
}
}
};
析构函数有了变化,那么构造函数也有变化吗?答案是确实有也变化。
构造的变化:
下面是 msvc 中 jthread 的有参构造函数。
template <class _Fn, class... _Args, enable_if_t<!is_same_v<remove_cvref_t<_Fn>, jthread>, int> = 0>
_NODISCARD_CTOR explicit jthread(_Fn&& _Fx, _Args&&... _Ax) {
if constexpr (is_invocable_v<decay_t<_Fn>, stop_token, decay_t<_Args>...>) {
_Impl._Start(_STD forward<_Fn>(_Fx), _Ssource.get_token(), _STD forward<_Args>(_Ax)...);
} else {
_Impl._Start(_STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...);
}
}
在 if constexpr 中,会在编译期判断首个函数参数是否是 std::stop_token。基于这个条件的分支进行具体的线程创建。而 else 中就是在 C++11 中创建线程的常规方式。
而 std::stop_token 是什么,为什么需要这个将在后文中进行讲解。