asio中提供的timer名为deadline_timer,它提供了超时计时的功能。首先以一个最简单的同步Timer为例来演示如何使用它。
#include
#include
int main()
{
boost::asio::io_service
boost::asio::deadline_timer timer(io, boost::posix_time::seconds(3));
timer.wait();
std::cout << "Hello, world!\n";
return 0;
}
首先常见了一个io_service对象,它提供了IO调度功能,asio库中的所有io操作都是基于它来执行的。然后创建了一个deadline_timer对象,它有两个参数,一个是io_service对象,另一个是超时时间。
创建了timer后,就可以调用wait函数来阻塞等待至timer超时了,它还有一种可以指定错误码的入参的重载形式,关于错误码后面再介绍。
同步timer虽然简单,但由于其会阻塞,在实际的项目中并不常用,而往往使用的是异步timer:指定一个回调函数,计时器超时后执行回调函数。asio中实现异步timer比较简单,示例如下:
void print(const boost::system::error_code& /*e*/)
{
std::cout << "Hello, world!\n";
}
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer timer(io, boost::posix_time::seconds(5));
timer.async_wait(&print);
io.run();
return 0;
}
和同步方式相比,它主要有两点不同:
Timer还有一种常用操作是取消Timer,基本方法如下:
void print(const boost::system::error_code& err)
{
if(err)
{
std::cout << "timer is canceled\n";
return;
}
std::cout << "Hello, world!\n";
}
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer timer(io, boost::posix_time::seconds(5));
timer.async_wait(&print);
boost::asio::deadline_timer timer2(io, boost::posix_time::seconds(2));
timer2.wait();
timer.cancel();
io.run();
return 0;
}
可以通过expires_from_now和expires_at两个函数更改Timer的超时时间,如下示例就通过它实现一个周期计时器。
typedef std::function<void (const boost::system::error_code&)> timer_callback ;
void print(const boost::system::error_code&)
{
std::cout << "Hello, world!\n";
}
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer timer(io, boost::posix_time::seconds(1));
timer_callback callback = [&](const boost::system::error_code& err)
{
print(err);
timer.expires_at(timer.expires_at() + boost::posix_time::seconds(1));
timer.async_wait(callback);
};
timer.async_wait(callback);
io.run();
return 0;
}
PS:为了简单,这儿用到了c++11的语法,不想用c++11语法可以参考boost文档的原始示例。
//
// timer.cpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include
#include
#include
#include
class printer
{
public:
printer(boost::asio::io_service& io)
: timer_(io, boost::posix_time::seconds(1)),
count_(0)
{
timer_.async_wait(boost::bind(&printer::print, this));
}
~printer()
{
std::cout << "Final count is " << count_ << "\n";
}
void print()
{
if (count_ < 5)
{
std::cout << count_ << "\n";
++count_;
timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1));
timer_.async_wait(boost::bind(&printer::print, this));
}
}
private:
boost::asio::deadline_timer timer_;
int count_;
};
int main()
{
boost::asio::io_service io;
printer p(io);
io.run();
return 0;
}
=================================================================================================================================
#include
#include
#include
#include
#include
#include
using namespace std;
//超时控制器类
class TimerController
{
public:
/**
* 超时控制器构造函数
* @param ios 异步I/O对象
* @param callbackFunc 超时处理回调函数
* @param uiWaitSec 定时器间隔等待时间,单位:秒
*/
explicit TimerController(boost::asio::io_service &ios, boost::function callbackFunc, unsigned int uiWaitSec) :
m_timer(ios, boost::posix_time::seconds(3))
{
cout<< "1111111111111" << "-----" << time(NULL)< m_timeoutHandle; //超时处理回调函数
};
//构造函数
class CmdQueueManager
{
public:
CmdQueueManager(boost::asio::io_service* io)
{
m_pTimer = new TimerController(*io,boost::bind(&CmdQueueManager::SendProcess, this),1);
}
void SendProcess()
{
cout<< "1111111111111" << "-----" << time(NULL)<
最近做项目时,做了一个定时器,发现定时器回调函数不按照指定时间回调,总是延迟,后经研究发现,是IO出了问题,把一个IO绑定到多个socket上面,并把这个IO绑定到定时器上面,有一些socket连接网络时发出了一些connect行为,这些行为会造成IO阻塞,当然这只是猜测,看到的读者可以帮忙讲解一下。所以本人建议做timer时候,自建一个人“干净”的IO。