《探索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 标准库把底层都给封装好了,用起来很方便,但是太细节的东西要追究起来就比较难。

        若有理解失误或表达不清的地方,还请大家多多指教,谢谢~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值