首页 > 代码库 > boost::deadline_timer

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;
}

boost::deadline_timer