日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

boost库下的deadline_timer和steady_timer 区别

發布時間:2025/3/11 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 boost库下的deadline_timer和steady_timer 区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1:steady_timer的expires_from_now函數參數必須使用std::chrono

2:deadline_timer的expires_from_now函數參數必須使用boost::posix_time

聲明以下處之別人的整理中

3:boost::asio::deadline_timer使用的計量時間是系統時間,因此修改系統時間會影響deadline_timer的行為。例如,調用了expires_from_now設置1分鐘超時后,立刻把系統時間改成一天前,那么要過一天時間才會超時。這個特性可能會影響程序功能的正常使用,因此我們通常想要的是一個不會受系統時間影響的定時器。

事實上,boost::asio::steady_timer就是一個這樣的定時器,它基于std::chrono::steady_clock實現。std::chrono::steady_clock是一個穩定的時鐘,不隨系統時間變化而變化。既然如此,直接用steady_timer代替deadline_timer不就可以了嗎?理論上來說是可以的,但實際上,在Visual C++ 2013環境下,這是行不通的,因為Visual C++ 2013標準庫中的std::chronno::steady_clock并不符合標準,它仍然會受系統時間影響!

有三種方法可以解決這個問題。第一是升級到Visual C++ 2015,這個版本的std::chronno::steady_clock總算符合標準了;第二是修改boost的編譯選項,定義BOOST_ASIO_DISABLE_STD_CHRONO宏,這樣可以禁止boost使用std::chrono,轉而使用boost::chrono;第三是本文要介紹的方法,即定制deadline_timer,讓它變成穩定的定時器。

deadline_timer實際上是basic_deadline_timer的特化版本,它的定義如下:

typedef basic_deadline_timer<boost::posix_time::ptime> deadline_timer;
basic_deadline_timer是一個模板類,它的定義如下:

template<
? ? typename Time,
? ? typename TimeTraits = boost::asio::time_traits<Time>,
? ? typename TimerService = deadline_timer_service<Time, TimeTraits>>
class basic_deadline_timer : public basic_io_object< TimerService >
從以上定義的模板參數可以看出,basic_deadline_timer提供了靈活的可定制性。這里我們關注的重點是前面兩個模板參數,其中第一個參數Time指定時間值的類型,第二個參數TimeTraits指定時間值的特性類,特性類用來對時間值進行各種操作。TimeTraits使用boost::asio::time_traits作為默認值,而boost::asio::time_traits只有一個針對boost::posix_time::ptime(即deadline_timer使用的時間值類型)的特化版本,從這個特化版本的定義可以看到TimeTraits需要提供哪些接口,如下所示:

/// Time traits specialised for posix_time.
template <>
struct time_traits<boost::posix_time::ptime>
{
? /// The time type.
? typedef boost::posix_time::ptime time_type;

? /// The duration type.
? typedef boost::posix_time::time_duration duration_type;

? /// Get the current time.
? static time_type now()
? {
#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
? ? return boost::posix_time::microsec_clock::universal_time();
#else // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
? ? return boost::posix_time::second_clock::universal_time();
#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
? }

? /// Add a duration to a time.
? static time_type add(const time_type& t, const duration_type& d)
? {
? ? return t + d;
? }

? /// Subtract one time from another.
? static duration_type subtract(const time_type& t1, const time_type& t2)
? {
? ? return t1 - t2;
? }

? /// Test whether one time is less than another.
? static bool less_than(const time_type& t1, const time_type& t2)
? {
? ? return t1 < t2;
? }

? /// Convert to POSIX duration type.
? static boost::posix_time::time_duration to_posix_duration(
? ? ? const duration_type& d)
? {
? ? return d;
? }
};
可以看到,TimeTraits需要提供time_type和duration_type兩種類型來分別表示一個時間點和一段時間;需要提供now方法來獲取當前時間;需要提供add、subtract和less_than方法來計算和比較時間;最后還需要to_posix_duration方法把duration_type類型轉換成boost::posix_time::time_duration類型。

顯然,對于定制的basic_deadline_timer,時間值類型Time可以是任意類型,并且它的含義并沒有硬性規定,例如,它可以是以毫秒或納秒為單位的時間,也可以是CPU時鐘的周期數,只要提供了正確的TimeTraits特性類把這個定制的時間值轉換成boost認識的時間值即可。

接下來要選擇一種與系統時間無關的時間值類型來定制basic_deadline_timer。在Windows平臺下,很容易想到可以使用QueryPerformanceCounter和QueryPerformanceFrequency,這兩個API提供了高精度的時間度量,與系統時間無關。QueryPerformanceCounter用來查詢當前CPU時鐘的周期數,是64位整數,這個是理想的時間值類型。要把CPU時鐘周期數轉換成具體的時間還需要調用QueryPerformanceFrequency查詢CPU時鐘的頻率,即1秒內的CPU時鐘周期數,然后通過簡單的計算即可得到。

下面的是使用QueryPerformanceCounter和QueryPerformanceFrequency定制的TimeTraits:

class TimeTraits {
public:
? ? typedef std::int64_t time_type;

? ? class duration_type {
? ? public:
? ? ? ? duration_type() : value(0) { }
? ? ? ? duration_type(std::int64_t value) : value(value) { }

? ? ? ? std::int64_t value;
? ? };

public:
? ? static void Initialize() {

? ? ? ? LARGE_INTEGER frequence_large_integer = { 0 };
? ? ? ? QueryPerformanceFrequency(&frequence_large_integer);
? ? ? ? frequence = frequence_large_integer.QuadPart;
? ? }

? ? static duration_type GetMinutes(std::int64_t minutes) {
? ? ? ? return duration_type(minutes * 60 * frequence);
? ? }

? ? static duration_type GetSeconds(std::int64_t seconds) {
? ? ? ? return duration_type(seconds * frequence);
? ? }

? ? static duration_type GetMilliseconds(std::int64_t milliseconds) {
? ? ? ? return duration_type(milliseconds * (frequence / 1000));
? ? }

? ? static time_type now() {

? ? ? ? LARGE_INTEGER counter = { 0 };
? ? ? ? QueryPerformanceCounter(&counter);
? ? ? ? return counter.QuadPart;
? ? }

? ? static time_type add(time_type time, duration_type duration) {
? ? ? ? return time + duration.value;
? ? }

? ? static duration_type subtract(time_type time1, time_type time2) {
? ? ? ? return duration_type(time1 - time2);
? ? }

? ? static bool less_than(time_type time1, time_type time2) {
? ? ? ? return time1 < time2;
? ? }

? ? static boost::posix_time::time_duration to_posix_duration(duration_type duration) {

? ? ? ? std::int64_t microseconds = (duration.value * 1000 * 1000) / frequence;
? ? ? ? return boost::posix_time::microseconds(microseconds);
? ? }

private:
? ? TimeTraits();

private:
? ? static std::int64_t frequence;
};
CPU時鐘的頻率是固定的,只需要調用QueryPerformanceFrequency查詢一次即可,因此這里增加了Initialize方法來初始化CPU時鐘頻率,要在程序啟動后的某個時機來調用該方法進行初始化。要注意的是duration_type不能跟time_type相同,這是TimeTraits的硬性規定,boost內部的代碼依賴了這個規定,違反它會導致編譯失敗。所以要針對duration_type額外定義一個看似冗余的類型。

另一個值得注意的地方是,上面的定義增加了GetMinutes、GetSeconds和GetMilliseconds方法,這幾個方法用來將具體的時間轉換成我們定制的時間值,即CPU時鐘周期數。這是因為在調用定時器的expires_from_now等方法設置超時值的時候,必須使用TimeTraits的duration_type,提供這幾個方法可以方便使用。

最后,將這個定制的TimeTraits作為basic_deadline_timer的模板參數即可:

typedef boost::asio::basic_deadline_timer<std::int64_t, TimeTraits> Timer
使用方法基本上與dealine_timer一樣,如下所示:


//在某個時機初始化TimeTraits
TimeTraits::Initialize();

//在某個地方定義io_service
boost::asio::io_service io_service;

//使用定制的Timer
Timer timer(io_service);
timer.expires_from_now(TimeTraits::GetSecnods(10));
timer.wait();

?
? ?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的boost库下的deadline_timer和steady_timer 区别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。