《探索C++多线程》:thread源码(⼆)
接上⼀篇⽂章,分析thread的内部类id 和命名空间this_thread。
namespace this_thread
this_thread中有四个函数,分别是:get_id()、yield()、sleep_for()、sleep_until(),它们的定义如下:
namespace this_thread {
thread::id get_id() _NOEXCEPT;
inline void yield() _NOEXCEPT { // 让出时间⽚
if (::Concurrency::details::_CurrentScheduler::_Id() != -1) { // 放弃,然后退出
::Concurrency::details::_Context::_Yield();
return;
}
_Thrd_yield();
}
inline void sleep_until(const stdext::threads::xtime *_Abs_time) { // 休眠当前线程,直到指定的时间点达到
if (::Concurrency::details::_CurrentScheduler::_Id() != -1) {
stdext::threads::xtime _Now;
stdext::threads::xtime_get(&_Now, stdext::threads::TIME_UTC);
::Concurrency::wait(_Xtime_diff_to_millis2(_Abs_time, &_Now));
return;
}
_Thrd_sleep(_Abs_time);电影源代码人物介绍
}
template<class _Clock, class _Duration> inline
void sleep_until( const chrono::time_point<_Clock, _Duration>& _Abs_time) { // 休眠当前线程,直到指定的时间点达到
stdext::threads::xtime _Tgt;
_Tgt.sec = chrono::duration_cast<chrono::seconds>(
_Abs_time.time_since_epoch()).count();
_Tgt.nsec = (long)chrono::duration_cast<chrono::nanoseconds>(
_Abs_time.time_since_epoch() - chrono::seconds(_Tgt.sec)).count();
sleep_until(&_Tgt);
}
template<class _Rep, class _Period> inline
void sleep_for(const chrono::duration<_Rep, _Period>& _Rel_time) { // 休眠指定的时间,实际使⽤sleep_for来实现
stdext::threads::xtime _Tgt = _To_xtime(_Rel_time);
sleep_until(&_Tgt);
}
} // namespace this_thread
inline thread::id this_thread::get_id() _NOEXCEPT {
return (_Thrd_current()); // 返回当前线程id
}
解释如下:
this_thread::get_id():返回当前线程;
this_thread::yield():让出时间⽚(线程的状态转变:执⾏状态—>可执⾏状态);
(防⽌当前线程独占CPU资源⽽使得其他线程得不到响应,因此主动让出抢到的时间⽚A,让其他线程去抢夺时间⽚A,⽽当前线程不参与时间⽚A的抢夺。当时间⽚A被其他线程使⽤完后,由操作系统调⽤,当前线程再与其他线程⼀同抢夺下⼀时间⽚);
this_thread::sleep_for():使当前线程休眠指定时间(线程的状态转变:执⾏状态—>休眠状态—>可执⾏状态);
this_thread::sleep_until():休眠当前线程,直到指定时间点到来(线程的状态转变:执⾏状态—>休眠状态—>可执⾏状态);class id
再来看class id,其声明和定义如下:
class thread::id { // thread id
public:
id() _NOEXCEPT { // 构造函数,空线程id
_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 bit值
return (_STD hash<size_t>()((size_t)_Thr_val(_Thr)));
}
private:
id(const thread& _Thrd) : _Thr(_Thrd._Thr) { } // 构造函数
id(_Thrd_t _Thrd) : _Thr(_Thrd) { } // 构造函数
_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;
};
inline bool operator==(thread::id _Left, thread::id _Right) _NOEXCEPT { // 若⼆者是同⼀线程,则返回true;否则,返回false
return (_Thrd_equal(_Left._Thr, _Right._Thr));
}
inline bool operator!=(thread::id _Left, thread::id _Right) _NOEXCEPT { // 若⼆者⾮同⼀线程,则返回true;否则,返回false
return (!(_Left == _Right)); // 调⽤了重载的 == 符号
}
inline bool operator<(thread::id _Left, thread::id _Right) _NOEXCEPT { // 若线程_Left先于_Right,则返回true;否则,返回false
return (_Thrd_lt(_Left._Thr, _Right._Thr));
}
inline bool operator<=(thread::id _Left, thread::id _Right) _NOEXCEPT { // 若线程_Left先于或等于_Right,则返回true;否则,返回false return (!(_Right < _Left)); // 调⽤了重载的 < 符号
}
inline bool operator>(thread::id _Left, thread::id _Right) _NOEXCEPT { // 若线程_Left后于_Right,则返回true;否则,返回false
return (_Right < _Left); // 调⽤了重载的 < 符号
}
inline bool operator>=(thread::id _Left, thread::id _Right) _NOEXCEPT { // 若线程_Left后于或等于_Right,则返回true;否则,返回false return (!(_Left < _Right)); // 调⽤了重载的 < 符号
}
// TEMPLATE STRUCT SPECIALIZATION hash
template<>
struct hash<thread::id> : public unary_function<thread::id, size_t> { // hash functor for thread::id
typedef thread::id _Kty;
size_t operator()(const _Kty& _Keyval) const { // hash _Keyval to size_t value by pseudorandomizing transform
return (_Keyval.hash());
}
};
好了,⼤概就是这样。这⾥没有太多好分析的,C++ 11 标准库把底层都给封装好了,⽤起来很⽅便,但是太细节的东西要追究起来就⽐较难。若有理解失误或表达不清的地⽅,还请⼤家多多指教,谢谢~
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论