在创建一个thread实例以后,提供了以下几个函数接口:
detach();//detach therad
意思是在构造thread之后,可以该线程与实例分离,然后即使在该变量被收回之后仍然能执行该线程
void detach()
{ // detach thread
if (!joinable())
_Throw_Cpp_error(_INVALID_ARGUMENT);
_Thrd_detachX(_Thr);
_Thr_set_null(_Thr);
}
get_id(); return id for this thread
inline thread::id thread::get_id() const _NOEXCEPT
{ // return id for this thread
return (id(*this));
}
join();等待前一个线程执行完之后才执行
inline void thread::join()
{ // join thread
if (!joinable())
_Throw_Cpp_error(_INVALID_ARGUMENT);
if (_Thr_is_null(_Thr))
_Throw_Cpp_error(_INVALID_ARGUMENT);
if (get_id() == _STD this_thread::get_id())
_Throw_Cpp_error(_RESOURCE_DEADLOCK_WOULD_OCCUR);
if (_Thrd_join(_Thr, 0) != _Thrd_success)
_Throw_Cpp_error(_NO_SUCH_PROCESS);
_Thr_set_null(_Thr);
}
joinable();//判断该线程是否是可执行线程
bool joinable() const _NOEXCEPT
{ // return true if this thread can be joined
return (!_Thr_is_null(_Thr));
}
看看宏定义:
#define _Thr_is_null(thr) (thr._Id == 0)
可以发现joinable就是返回id是否是等于0,如果等于0,就返回为false,即认为该线程不可执行
可以看到id是thread类里面声明的一个类,找到id的定义
class thread::id
{ // thread id
public:
id() _NOEXCEPT
{ // id for no thread
_Thr_set_null(_Thr);
}
template<class _Ch,
class _Tr>
basic_ostream<_Ch, _Tr>& _To_text(
basic_ostream<_Ch, _Tr>& _Str)
{ // insert representation into stream
return (_Str << _Thr_val(_Thr));
}
size_t hash() const
{ // hash bits to size_t value by pseudorandomizing transform
return (_STD hash<size_t>()((size_t)_Thr_val(_Thr)));
}
private:
id(const thread& _Thrd)
: _Thr(_Thrd._Thr)
{ // construct from thread object
}
id(_Thrd_t _Thrd)
: _Thr(_Thrd)
{ // construct from thread identifier
}
_Thrd_t _Thr;
friend thread::id thread::get_id() const _NOEXCEPT;
friend thread::id this_thread::get_id() _NOEXCEPT;
friend bool operator==(thread::id _Left, thread::id _Right) _NOEXCEPT;
friend bool operator<(thread::id _Left, thread::id _Right) _NOEXCEPT;
};
继续追踪,宏定义
#define _Thr_set_null(thr) (thr._Id = 0)
可以发现,其在构造时就是为0,也就是任何一个id,没做任何操作之前就是0.
hardware_concurrency();//这是一个静态成员函数,返回硬件线程上下文的数量,检测硬件的并发特性
static unsigned int hardware_concurrency() _NOEXCEPT
{ // return number of hardware thread contexts
return (::Concurrency::details::_GetConcurrency());
}
swap(thread& _other);//交换两个线程的状态
void swap(thread& _Other) _NOEXCEPT
{ // swap with _Other
_STD swap(_Thr, _Other._Thr);
}
template<class _Ty> inline
void swap(_Ty& _Left, _Ty& _Right)
_NOEXCEPT_OP(is_nothrow_move_constructible<_Ty>::value
&& is_nothrow_move_assignable<_Ty>::value)
{ // exchange values stored at _Left and _Right
_Ty _Tmp = _Move(_Left);
_Left = _Move(_Right);
_Right = _Move(_Tmp);
}
还有一个native_handle();就是返回它的handle,暂时没发现它的作用
下面写了一个小demo,可以供大家看一下
#include "stdafx.h"
#include "iostream"
#include "thread"
void show_num(int i)
{
std::cout << i << std::endl;
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "并发数量:" << std::thread::hardware_concurrency() << std::endl;
for (unsigned int i = 0; i < 5; i++)
{
std::thread t_in([i]{std::cout << i; });
std::cout<<"id:"<<t_in.get_id()<<std::endl;
if (i % 2)
{
t_in.detach();
std::cout << "t has be detached" << std::endl;
}
if (t_in.joinable())
{
std::cout << "thread can join" << std::endl;
t_in.join();
}
auto t_handle=t_in.native_handle();
}
std::thread t(show_num,5);
t.detach();
std::thread t1(show_num,5);
t1.swap(t);
if (t.joinable())
{
t.join();
std::cout << "t can join" << std::endl;
}
if (t1.joinable())
{
t1.join();
std::cout << "t1 can join" << std::endl;//交换之后,t1可以join的状态被交换给t了,所以,t又可以join了
}
//getchar();
return 0;
}