一. std::thread类
(一)thread类摘要及分析
class thread { // class for observing and managing threads public: class id; using native_handle_type = void*; thread() noexcept : _Thr{} { // 创建空的thread对象,实际上线程并未被创建! } private: template <class _Tuple, size_t... _Indices> static unsigned int __stdcall _Invoke(void* _RawVals) noexcept { // enforces termination //接口适配:将用户的可调用对象与_beginthreadex的接口进行适配。 //子线程重新拥有从主线程转让过来的保存着thread参数副本的tuple堆对象的所有权。 const unique_ptr<_Tuple> _FnVals(static_cast<_Tuple*>(_RawVals)); _Tuple& _Tup = *_FnVals; _STD invoke(_STD move(_STD get<_Indices>(_Tup))...); //注意,由于tuple中保存的都是副本,因此所有的参数都以右值的方式被转发出去。 _Cnd_do_broadcast_at_thread_exit(); // TRANSITION, ABI return 0; } template <class _Tuple, size_t... _Indices> _NODISCARD static constexpr auto _Get_invoke( index_sequence<_Indices...>) noexcept { // select specialization of _Invoke to use return &_Invoke<_Tuple, _Indices...>; //这里返回特化的_Invoke函数指针 } public: template <class _Fn, class... _Args, class = enable_if_t<!is_same_v<_Remove_cvref_t<_Fn>, thread>>> explicit thread(_Fn&& _Fx, _Args&& ... _Ax) { // construct with _Fx(_Ax...) using _Tuple = tuple<decay_t<_Fn>, decay_t<_Args>...>; //将传入thread的所有参数保存着tuple //在堆上创建tuple以按值保存thread所有参数的副本,指针用unique_ptr来管理。 auto _Decay_copied = _STD make_unique<_Tuple>(_STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...); //创建tuple的智能指针 constexpr auto _Invoker_proc = _Get_invoke<_Tuple>(make_index_sequence<1 + sizeof...(_Args)>{}); //获取线程函数地址 //在Windows系统中,会调用_beginthredex来创建新线程。其中,_Invoker_proc为线程函数地址,它要求的参数为tuple的指针,即_Decay_copied.get() //注意:线程创建后即立即运行(第5个参数为0),原生的线程id保存在_Thr._Id中,句柄保存在_Thr._Hnd。 _Thr._Hnd = reinterpret_cast<void*>(_CSTD _beginthreadex(nullptr, 0, _Invoker_proc, _Decay_copied.get(), 0, &_Thr._Id)); if (_Thr._Hnd == nullptr) { // failed to start thread _Thr._Id = 0; _Throw_Cpp_error(_RESOURCE_UNAVAILABLE_TRY_AGAIN); } else { // ownership transferred to the thread (void)_Decay_copied.release(); //转让tuple的所有权给新的线程。 } } ~thread() noexcept { // clean up if (joinable()) { //注意,std::thread析构时,如果线程仍可joinable,则会调用terminate终止程序! _STD terminate(); } } thread(thread&& _Other) noexcept : _Thr(_STD exchange(_Other._Thr, {})) { // move from _Other } thread& operator=(thread&& _Other) noexcept { // move from _Other if (joinable()) { _STD terminate(); } _Thr = _STD exchange(_Other._Thr, {}); return *this; } thread(const thread&) = delete; //thread对象不能被复制 thread& operator=(const thread&) = delete; //thread对象不能被拷贝赋值 void swap(thread& _Other) noexcept { // swap with _Other _STD swap(_Thr, _Other._Thr); } _NODISCARD bool joinable() const noexcept { // return true if this thread can be joined return _Thr._Id != 0; //原生的线程id不为0,表示底层的线程己经创建 } void join() { // join thread if (!joinable()) { _Throw_Cpp_error(_INVALID_ARGUMENT); } if (_Thr._Id == _Thrd_id()) { _Throw_Cpp_error(_RESOURCE_DEADLOCK_WOULD_OCCUR); } if (_Thrd_join(_Thr, nullptr) != _Thrd_success) { _Throw_Cpp_error(_NO_SUCH_PROCESS); } _Thr = {}; //注意调用join以后,原生线程id被清零,意味着join只能被调用一次! } void detach() { // detach thread if (!joinable()) { _Throw_Cpp_error(_INVALID_ARGUMENT); } _Check_C_return(_Thrd_detach(_Thr)); //线程被分离,成为后台线程 _Thr = {}; //注意调用detach以后,原生线程id被清零,意味着detach也只能被调用一次! } _NODISCARD id get_id() const noexcept; _NODISCARD static unsigned int hardware_concurrency() noexcept { // return number of hardware thread contexts return _Thrd_hardware_concurrency(); } _NODISCARD native_handle_type native_handle() { // return Win32 HANDLE as void * return _Thr._Hnd; } private: _Thrd_t _Thr; };