boost::deadline_timer

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章