deadline_timer相关类介绍
deadline_timer众所周知,是asio的一个核心定时器,支持同步定时触发和异步定时触发。具体有什么功能如何使用这里不作介绍,本文主要从deadline_timer的wait和async_wait入手,解释deadline_timer的实现逻辑。
先解释下deadline_timer的大致结构。deadline_timer实际上是别名,它的真正名字叫basic_deadline_timer:
/// Typedef for the typical usage of timer. Uses a UTC clock.
typedef basic_deadline_timer<boost::posix_time::ptime> deadline_timer;
这里的模板类表示表达时间的类型,对于这个时间类型这里不深究,知道它用来处理时间就行了。
而basic_deadline_timer继承自basic_io_object<detail::deadline_timer_service<TimeTraits>>
这个deadline_timer_service是deadline_timer的服务类,众所周知,想在io_service中搞事,都得通过服务类来进行操作,说简单点,就是basic_deadline_timer中的函数实际上都是调用deadline_timer_service的接口。
而basic_io_object中实际上持有一个deadline_timer_service对象和另一个数据对象(我也不知道怎么形容这个,暂称为数据对象)。下面源码中的IoObjectService模板参数就是deadline_timer_service
template <typename IoObjectService, // 这个IoObjectService就是deadline_timer_service
bool Movable = detail::service_has_move<IoObjectService>::value>
class basic_io_object
{
public:
/// The type of the service that will be used to provide I/O operations.
typedef IoObjectService service_type;
/// The underlying implementation type of I/O object.
typedef typename service_type::implementation_type implementation_type; // 这个就是数据对象类型
// 。。。
private:
// The service associated with the I/O object.
service_type& service_;
/// The underlying implementation of the I/O object.
implementation_type implementation_; // 数据对象
这个implementation_type就是我所说的数据对象(的类型)了。直接看到deadline_timer_service中implementation_type的定义:
// The implementation type of the timer. This type is dependent on the
// underlying implementation of the timer service.
struct implementation_type
: private boost::asio::detail::noncopyable
{
time_type expiry; // 表示时间,time_type是模板参数
bool might_have_pending_waits; // 表明是否还有要等待的操作
typename timer_queue<Time_Traits>::per_timer_data timer_data; // 用于存放到epoll_reactor的定时器队列中
};
上面的per_timer_data可能不是很好理解,deadline_timer调用async_wait后会往epoll_reactor的定时器队列中存一个元素,这个元素的类型就是这个per_timer_data。而这个epoll_reactor就是一个触发器,基于篇幅原因,这里就不多说了,仅需要知道这是一个类似epoll的包装类就行了。(类似epoll只是说部分功能相似,这两者区别还是很大的)为了方便理解,还是上源码:
class timer_queue : public timer_queue_base
{
public:
class per_timer_data
{
public:
per_timer_data() :
heap_index_((std::numeric_limits<std::size_t>::max)()),
next_(0), prev_(0)
{
}
private:
friend class timer_queue;