1. 程式人生 > >boost庫asio詳解4——deadline_timer使用說明

boost庫asio詳解4——deadline_timer使用說明

deadline_timer和socket一樣,都用io_service作為建構函式的引數。也即,在其上進行非同步操作,都將導致和io_service所包含的iocp相關聯。這同樣意味著在析構 io_service之前,必須析構關聯在這個io_service上的deadline_timer。

1. 建構函式

在構造deadline_timer時指定時間。
[cpp]view plaincopyprint?
  1. basic_deadline_timer(  
  2.     boost::asio::io_service & io_service);  
  3. basic_deadline_timer(  
  4.     boost::asio::io_service & io_service,  
  5.     const time_type & expiry_time);  
  6. basic_deadline_timer(  
  7.     boost::asio::io_service & io_service,  
  8.     const duration_type & expiry_time);  
注意後兩種的區別。以下2種用法是等價的:
[cpp]view plaincopyprint?
  1. boost::asio::deadline_timer t(io, boost::posix_time::microsec_clock::universal_time()+boost::posix_time::seconds(5));  
  2. boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));  
前者是絕對時間,後者是相對時間。

2. 同步

一個deadline_timer只維護一個超時時間,一個deadline_timer不同時維持多個定時器。
[cpp]view plaincopyprint?
  1. void wait();  
  2. void wait(boost::system::error_code& ec);  
這是個同步等待函式,例如:
[cpp]view plaincopyprint?
  1. boost::asio::io_service io;  
  2. boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));  
  3. t.wait();  
由於不涉及到非同步,該函式和io_service沒什麼關係。這個函式在windows下的實現就只是簡單的sleep。因此也就不存在cancel之說。

3. 非同步

[cpp]view plaincopyprint?
  1. template<typename WaitHandler>  
  2. void async_wait(WaitHandler handler);  
注意這個error很重要,表明這個handler是因為超時被執行還是因為被cancel。
符合2種情況之一,handler被執行:超時或者被cancel。
這同時隱含的說明了除非io.stop被呼叫,否則handler一定會被執行。即便是被cancel。
被cancel有多種方法,直接呼叫cancel或者呼叫expires_at,expires_from_now重新設定超時時間。

4. 例子

[cpp]view plaincopyprint?
  1. namespace
  2. {  
  3.     void print(const boost::system::error_code&)  
  4.     {  
  5.         PRINT_DEBUG("Hello, world!");  
  6.     }  
  7.     void handle_wait(const boost::system::error_code& error,  
  8.                      boost::asio::deadline_timer& t,   
  9.                      int& count)  
  10.     {  
  11.         if(!error)  
  12.         {  
  13.             PRINT_DEBUG(count);  
  14.             if(count++ < 5)  
  15.             {  
  16.                 t.expires_from_now(boost::posix_time::seconds(3));  
  17.                 t.async_wait(boost::bind(handle_wait,   
  18.                                          boost::asio::placeholders::error,  
  19.                                          boost::ref(t),  
  20.                                          boost::ref(count)));  
  21.                 if (count == 3)  
  22.                 {  
  23.                     t.cancel();  
  24.                 }  
  25.             }  
  26.         }  
  27.     }   
  28. }  
  29. // 同步方法
  30. void test_timer_syn()  
  31. {  
  32.     boost::asio::io_service ios;  
  33.     boost::asio::deadline_timer t(ios, boost::posix_time::seconds(3));  
  34.     PRINT_DEBUG(t.expires_at());  
  35.     t.wait();  
  36.     PRINT_DEBUG("Hello syn deadline_timer!");  
  37. }  
  38. // 非同步方法: 3秒後執行print方法. 
  39. void test_timer_asyn()  
  40. {  
  41.     boost::asio::io_service io;  
  42.     boost::asio::deadline_timer t(io, boost::posix_time::seconds(3));  
  43.     t.async_wait(print);  
  44.     PRINT_DEBUG("After async_wait...");  
  45.     io.run();  
  46. }  
  47. // 非同步迴圈執行方法: 
  48. void test_timer_asyn_loop()  
  49. {  
  50.     boost::asio::io_service io;  
  51.     boost::asio::deadline_timer t(io);  
  52.     size_t a = t.expires_from_now(boost::posix_time::seconds(1));  
  53.     int count = 0;  
  54.     t.async_wait(boost::bind(handle_wait,   
  55.                              boost::asio::placeholders::error,  
  56.                              boost::ref(t),  
  57.                              boost::ref(count)));  
  58.     io.run();      
  59. }