boost::deadline_timer
定義
typedef basic_deadline_timer<boost::posix_time::ptime> deadline_timer;
basic_deadline_timer是個模板類。
構造函數
deadline_timer有三個構造函數:
1 explicit basic_deadline_timer(boost::asio::io_service& io_service)
: basic_io_object<TimerService>(io_service)
{
}
構造函數有一個參數io_service,幾乎所有asio的程序都用到io_service(這個類以後再學習)。這個
構造函數創建了一個沒有結束時間的定時器。在使用這個定時器之前,我們必須條用其成員函數expires_at或
expires_from_now來設置結束時間。
例子:
boost::asio::deadline_timer t1(io);
t1.expires_from_now(boost::posix_time::seconds(1));//從現在開始1秒後結束
2 basic_deadline_timer(boost::asio::io_service& io_service, const time_type& expiry_time)
: basic_io_object<TimerService>(io_service)
{
}
此構造函數有兩個參數,第二個函數類型time_type對deadlien_timer來說是ptime類型,這個構造函數創建了一個絕對時間的定時器。定時器在時間爲expiry_time時結束。
例子:
std::string abstime = "2015-01-22 13:10:23"
boost::asio::deadline_timer t2(io, boost::posix_time::time_from_string(abstime));//構造一個絕對定失效的定時器
這裏time_from_string()函數會把abstime轉換成ptime類型的時間
3 basic_deadline_timer(boost::asio::io_service& io_service, const duration_type& expiry_time)
: basic_io_object<TimerService>(io_service)
{
}
此構造函數也有兩個參數,第二個參數類型duration_type是個相對時間,相對當前時間可以秒、分、時等等。
例子:
boost::asio::deadline_timer t(io, boost::posix_time::seconds(2));//從當前時間開始2s以後結束
成員函數
1 std::size_t cancel()
此函數將取消定時器;同時任何在等待此定時器的異步操作都被取消,所有被取消異步操作的handler都會被調用,參數error_code被設置爲boost::asio::error::operation_aborted。
返回被取消異步操作的個數,同時拋出boost::system::system_error Thrown on failure。 注意當在調用cancel這個函數時,定時器剛好結束,任何在等待被調用隊列的異步操作將不會被取消,任何正在被調用的異步操作將不會被取消。
2 std::size_t cancel(boost::system::error_code& ec)
這個函數的作用和無參數的cancel()函數作用相同。在調用此函數時如果出現錯誤,參數ec指出出現什麼錯誤。
3 std::size_t cancel_one()
此函數將取消定時器,並且強制一個在等待此定時器的異步操作被被取消,這個被取消異步操作的handler被調用,調用順FIFO,參數error_code被設置爲boost::asio::error::operation_aborted。
返回值爲0或1。
注意其他在等待的異步操作在定時器結束時,還會被調用,看例子:
void handle_expriesfn(const boost::system::error_code& error, int flag)
{
if (error != boost::asio::error::operation_aborted)
{
flag ? (std::cout << "I have something to do..." << std::endl) :
(std::cout << "I have nothing to do....." << std::endl);
}
else
{
std::cout << __FUNCTION__ << " handler is invalid" << std::endl;
}
}
void test_cancel()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(2));
t.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, 0));
t.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, 1));
boost::system::error_code err;
t.cancel_one(err);//第一個handler會立即被調用error_code被置爲boost::asio::error::operation_aborted,第二個handler在定時器結束時才被調用
io.run();
}
4 time_type expires_at() const
返回定時器當前的結束時間(定時器結束時間可以被重置)。
5 std::size_t expires_at(const time_type& expiry_time)
重新設置定時器的結束時間。參數expiry_time是絕對時間。
注意任何在等待此定時器的異步操作都被取消,所有被取消異步操作的handler都會被調用,參數error_code被設置爲boost::asio::error::operation_aborted。
返回被取消異步操作的個數,同時拋出boost::system::system_error Thrown on failure。
當在調用expires_at這個函數時,定時器剛好結束,任何在等待被調用隊列的異步操作將不會被取消,任何正在被調用的異步操作將不會被取消。
列子:
void on_any_event(boost::asio::deadline_timer& timer, int flag)
{
//expires_at(abstime)函數重新設置定時器時間,以前正在等待此定時器的handler都會被取消
//返回被取消的handler個數(return The number of asynchronous operations that were canceled)
size_t cancelednum = timer.expires_at(timer.expires_at() + boost::posix_time::seconds(2));
if (cancelednum > 0)
{
std::cout << "the canceled handler is " << cancelednum << std::endl;
timer.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, flag));
timer.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, !flag));
}
else
{
std::cout << "too late, timer has expried" <<std::endl;
}
}
void test_expires_at()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(2));
t.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, 0));
t.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, 1));
on_any_event(t, 0);//取消定時器
io.run();
}
6 std::size_t expires_at(const time_type& expiry_time, boost::system::error_code& ec)
這個函數作用同第5個函數。在調用此函數時如果出現錯誤,參數ec指出出現什麼錯誤。
7 duration_type expires_from_now() const
返回定時器從現在開始到結束時的時間。
8 std::size_t expires_from_now(const duration_type& expiry_time)
重新設置定時器的結束時間,這個時間相對當前時間的。
注意任何在等待此定時器的異步操作都被取消,所有被取消異步操作的handler都會被調用,參數error_code被設置爲boost::asio::error::operation_aborted。
返回被取消異步操作的個數,同時拋出boost::system::system_error Thrown on failure。
當在調用expires_at這個函數時,定時器剛好結束,任何在等待被調用隊列的異步操作將不會被取消,任何正在被調用的異步操作將不會被取消。
例子:
void on_some_event(boost::asio::deadline_timer& timer, int flag)
{
//expires_from_now(relativetime)函數重新設置定時器時間,以前正在等待此定時器的handler都會被取消
//返回被取消的handler個數(return The number of asynchronous operations that were cancelled)
size_t cancelednum = timer.expires_from_now(boost::posix_time::seconds(2));
if (cancelednum > 0)
{
std::cout << "the cancelled handler is " << cancelednum << std::endl;
timer.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, flag));
}
else
{
std::cout << "too late, timer has expried" <<std::endl;
}
}
void test_expries_from_now()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(2));
t.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, 0));
t.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, 1));
on_some_event(t, 0);//取消定時器
io.run();
}
9 std::size_t expires_from_now(const duration_type& expiry_time, boost::system::error_code& ec)
這個函數作用同第8個函數。在調用此函數時如果出現錯誤,參數ec指出出現什麼錯誤。
10 void wait() or wait(boost::system::error_code& ec)
等待定時器結束。如果定時器不結束,此函數不返回。
11 async_wait(handler())
a 會立即返回,handler函數不會在這個函數這裏調用,
b handler會在定時器結束
c 或定時器被取消是調用,這時error_code值爲boost::asio::error::operation_aborted
下面是測試的列子:
deadtimer.h
void testSyncDT()
{
std::cout << "After 2s will output: ";
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(2));
t.wait();//wait()會阻塞直到定時器結束才返回
//下面的代碼不會執行直到wait函數返回
std::cout << "hello world" << std::endl;
std::cout << "After 1s will output: ";
boost::asio::deadline_timer t1(io);
t1.expires_from_now(boost::posix_time::seconds(1));//從現在開始1秒後結束
t1.wait();
std::cout << "hello world again" << std::endl;
}
void handler(const boost::system::error_code& error)
{
if (!error)
{
//do something...
std::cout << "handler is called" << std::endl;
}
else
{
std::cout << "handler is invalid" << std::endl;
}
}
void print_posix_time_to_string(const boost::system::error_code& error, const boost::posix_time::ptime& pt)
{
if (error != boost::asio::error::operation_aborted)
{
std::cout << "to_iso_string: " << boost::posix_time::to_iso_string(pt) << std::endl;
std::cout << "to_iso_extended_string: " << boost::posix_time::to_iso_extended_string(pt) << std::endl;
std::cout << "to_sample_string: " << boost::posix_time::to_simple_string(pt) << std::endl;
}
else
{
std::cout << __FUNCTION__ << " handler is invalid" << std::endl;
}
}
void testAsyncDT()
{
boost::posix_time::ptime postime = boost::posix_time::second_clock::local_time();
std::string strt = boost::posix_time::to_iso_extended_string(postime);
std::cout << strt << std::endl;
boost::posix_time::ptime pst = boost::posix_time::time_from_string("2015-01-22 15:38:00");
std::cout << pst << std::endl;
boost::asio::io_service io;//構造一個相對的定時器
boost::asio::deadline_timer t(io, boost::posix_time::seconds(2));
t.async_wait(&handler);
//async_wait()會立即返回,handler函數不會在這裏調用,
//handler會在定時器結束
//或定時器被取消是調用,這時error_code值爲boost::asio::error::operation_aborted
std::cout << "async is called" << std::endl;
//注意不要直接使用本地(如2015-01-22 15:38:00)時間,否則要等待很長時間
boost::posix_time::ptime pt2 = t.expires_at() + boost::posix_time::seconds(3);
std::string abstime = boost::posix_time::to_simple_string(pt2);
boost::asio::deadline_timer t2(io, boost::posix_time::time_from_string(abstime));//構造一個絕對定失效的定時器
t2.async_wait(boost::bind(&print_posix_time_to_string, boost::asio::placeholders::error, pt2));
t2.cancel();//取消定時器
io.run();//異步操作必須調用run()
}
void handle_expriesfn(const boost::system::error_code& error, int flag)
{
if (error != boost::asio::error::operation_aborted)
{
flag ? (std::cout << "I have something to do..." << std::endl) :
(std::cout << "I have nothing to do....." << std::endl);
}
else
{
std::cout << __FUNCTION__ << " handler is invalid" << std::endl;
}
}
void on_some_event(boost::asio::deadline_timer& timer, int flag)
{
//expires_from_now(relativetime)函數重新設置定時器時間,以前正在等待此定時器的handler都會被取消
//返回被取消的handler個數(return The number of asynchronous operations that were cancelled)
size_t cancelednum = timer.expires_from_now(boost::posix_time::seconds(2));
if (cancelednum > 0)
{
std::cout << "the cancelled handler is " << cancelednum << std::endl;
timer.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, flag));
}
else
{
std::cout << "too late, timer has expried" <<std::endl;
}
}
void test_expries_from_now()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(2));
t.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, 0));
t.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, 1));
on_some_event(t, 0);//取消定時器
io.run();
}
void handler_cancel(const boost::system::error_code& error)
{
if (error != boost::asio::error::operation_aborted)
{
testSyncDT();
}
else
{
std::cout << __FUNCTION__ << " handler is invalid" << std::endl;
}
}
void test_cancel()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(3));
t.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, 0));
t.async_wait(handler_cancel);
t.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, 1));
//boost::this_thread::sleep(boost::posix_time::seconds(3));
boost::system::error_code err;
t.cancel_one(err);//第一個handler會立即被調用error_code被置爲boost::asio::error::operation_aborted,第二個handler在定時器結束時才被調用
t.cancel_one(err);//注意這個地方
io.run();
}
void on_any_event(boost::asio::deadline_timer& timer, int flag)
{
//expires_at(abstime)函數重新設置定時器時間,以前正在等待此定時器的handler都會被取消
//返回被取消的handler個數(return The number of asynchronous operations that were canceled)
size_t cancelednum = timer.expires_at(timer.expires_at() + boost::posix_time::seconds(2));
if (cancelednum > 0)
{
std::cout << "the canceled handler is " << cancelednum << std::endl;
timer.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, flag));
timer.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, !flag));
}
else
{
std::cout << "too late, timer has expried" <<std::endl;
}
}
void test_expires_at()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(2));
t.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, 0));
t.async_wait(boost::bind(handle_expriesfn, boost::asio::placeholders::error, 1));
on_any_event(t, 0);//取消定時器
std::cout << t.expires_from_now() << std::endl;
io.run();
std::cout << t.expires_from_now() << std::endl;
}
main.cpp
#include "deadtime.h"
void testTime()
{
//smtlTimer::testSyncDT();
//smtlTimer::testAsyncDT();
//smtlTimer::test_expries_from_now();
smtlTimer::test_cancel();
//smtlTimer::test_expires_at();
}
int main()
{
testTime();
system("pause");
return 0;
}