实例分析:C++20的std::jthread

我们首先开门见山来介绍一下,在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 是什么,为什么需要这个将在后文中进行讲解。

相关推荐
啦啦啦啦啦zzzz3 天前
Appender抽象类的实现c++20
linux·服务器·c++·c++20
OPEN-F5 天前
C++20新特性精讲:概念、范围与三路比较
算法·c++20
小小龙学IT13 天前
C++ std::chrono 时间库深度解析:从 duration 模板到 C++20 日历与时区
linux·c++·c++20
郝学胜-神的一滴16 天前
C++20 高级编程 004:从初始化、内存到const系列关键字
开发语言·算法·编程·软件构建·c++20
可爱系程序猿16 天前
msvcp120.dll 加载失败排查:VC++ 2013、进程架构与插件私有目录如何对应
程序人生·电脑·c++20
ShineWinsu16 天前
对于C++:C++20中线程、初始化、Lambda与内存视图等特性的解析
c++·c++20
可爱系程序猿16 天前
mfc100.dll 加载失败排查:旧版 VC++ 2010 程序、位数与插件目录如何核对
程序人生·电脑·c++20
ShineWinsu19 天前
对于 C++:C++20中Concept(概念) 与 Coroutine(协程)的解析
linux·开发语言·网络·c++·c++20·epoll
Lzg_na1 个月前
C++20 Concept 核心概念、语法详解与三大工程实践场景
c++20
Billy121381 个月前
Day14-C++20 Modules:模块声明与导入、模块分区、与头文件对比、迁移策略
c++20·c++进阶学习