基于多线程并发-STL之thread构造函数浅析

一、标准库Thread内容(函数内部实现内容已摘去)

class thread
	{	// class for observing and managing threads
public:
	class id;
	typedef void *native_handle_type;
	thread() noexcept;
	template<class _Fn,
		class... _Args,
		class = enable_if_t<!is_same_v<remove_cv_t<remove_reference_t<_Fn>>, thread>>>
		explicit thread(_Fn&& _Fx, _Args&&... _Ax)
		{	// construct with _Fx(_Ax...)
		_Launch(&_Thr,
			_STD make_unique<tuple<decay_t<_Fn>, decay_t<_Args>...> >(
				_STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...));
		}
	~thread() noexcept;
	thread(thread&& _Other) noexcept
		: _Thr(_Other._Thr);
	thread& operator=(thread&& _Other) noexcept;
	thread(const thread&) = delete;
	thread& operator=(const thread&) = delete;
	void swap(thread& _Other) noexcept;
	_NODISCARD bool joinable() const noexcept;
	void join();
	void detach();
	_NODISCARD id get_id() const noexcept;
	_NODISCARD static unsigned int hardware_concurrency() noexcept;

	_NODISCARD native_handle_type native_handle();

private:
	thread& _Move_thread(thread& _Other);
	_Thrd_t _Thr;
	};

二、Thread类简单介绍
在介绍那个很复杂的构造函数前我们大致了解一下该类。
1、以下含义为thread被创建出来后不能进行拷贝和拷贝赋值,但是有move语义(c++11重要特性)。

thread(thread&& _Other) noexcept
	: _Thr(_Other._Thr);
thread& operator=(thread&& _Other) noexcept;
thread(const thread&) = delete;
thread& operator=(const thread&) = delete;
void swap(thread& _Other) noexcept;

2、常用接口(不是本篇的主题,将在另外文章中讲到,请参考:《C++11标准库thread简介》

void join();
void detach();
_NODISCARD id get_id() const noexcept;
_NODISCARD static unsigned int hardware_concurrency() noexcept;

三、复杂而重要的构造函数(本文的主题)

template<class _Fn,
		class... _Args,
		class = enable_if_t<!is_same_v<remove_cv_t<remove_reference_t<_Fn>>, thread>>>
		explicit thread(_Fn&& _Fx, _Args&&... _Ax)
		{	// construct with _Fx(_Ax...)
		_Launch(&_Thr,
			_STD make_unique<tuple<decay_t<_Fn>, decay_t<_Args>...> >(
				_STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...));
		}

1、模板参数部分

template<class _Fn,
		class... _Args,
		class = enable_if_t<!is_same_v<remove_cv_t<remove_reference_t<_Fn>>, thread>>>

1)class _Fn是设想匹配的是可调用对象(函数、成员函数、函数对象、lambda表达式)等。
2)class… _Args,匹配可调用对象的参数列,为C++11的重要特性Variadic Templates(…)和元组tuple。
3)以下内容我们由内到外一层一层分析(对萃取机和元编程要稍作了解)

class = enable_if_t<!is_same_v<remove_cv_t<remove_reference_t<_Fn>>, thread>>

a、remove_reference_t<_Fn>为退化_Fn的引用和右值引用。
b、remove_cv_t<#a#>在a的基础上再退化_Fn的const和volatile
c、is_same_v<#b#, thread>在b的基础上判断_Fn和thread是否为同种类型。
d、enable_if_t<!#c#>若c的结果为false则该构造函数模板匹配成功,否则失败,编译不通过。
e、class=#d#为匿名模板参数(一般匿名模板参数来完成对部分参数条件的校验,此处就是经典应用),并且没有占位。
小结:这么一大串是为了不和其他构造发生二义性,使得“1)”中_Fn为可调用对象的设想为真,而不是线程对象。
不同版本VS源码稍有差别,核心思想不会变。

四、延伸探讨

// construct with _Fx(_Ax...)
		_Launch(&_Thr,
			_STD make_unique<tuple<decay_t<_Fn>, decay_t<_Args>...> >(
				_STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...));

该构造函数的实现部分有兴趣的也可以研究研究。

如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大胡子的艾娃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值