Boost.ASIO源码:deadline_timer源码级解析(二)——epoll_reactor定时器逻辑

本文详细解析了Boost.ASIO中的epoll_reactor定时器逻辑,包括timerfd的创建、添加到epoll监听集,以及如何通过epoll_reactor::run捕获定时器触发。还介绍了interrupter的实现,用于中断阻塞的epoll_wait状态。
摘要由CSDN通过智能技术生成

前文回顾

前面讲deadline_timer::async_wait()讲到了epoll_reactor::scheduler_timer(),那时候讲得很模糊,这里稍微展开再讲解一下。首先先回顾下scheduler_timer的源码:

template <typename Time_Traits>
void epoll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
    const typename Time_Traits::time_type& time,
    typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op)
{
   
  mutex::scoped_lock lock(mutex_);

  if (shutdown_)
  {
   
    scheduler_.post_immediate_completion(op, false);
    return;
  }

  bool earliest = queue.enqueue_timer(time, timer, op);  // 把定时器添加到deadline_timer_service的timer_queue_成员中
  scheduler_.work_started();   // scheduler_的类型是scheduler,即io_service的实现类
  if (earliest)
    update_timeout();
}

// work_started是scheduler的成员函数
  void work_started()
  {
   
    ++outstanding_work_;
  }

本文主要关注第14行到第17行这段代码的逻辑。这段逻辑乍看之下十分的晦涩,这逻辑与epoll_reactor的实现逻辑紧密相关,接下来便讲解为何是这样的逻辑。

epoll_reactor大致介绍

epoll_reactor就是一种异步触发器,它的功能概括起来就是能在需要的时候触发scheduler来执行处理函数(这里的处理函数就是外面传进来的回调函数)。这个需要的时候分2种情况,一种是某个描述符变为可读或可写或出错,这个是通过epoll来实现的;另一种是定时器到时间了,这个是通过timerfd来实现的(实际上这个触发条件也是timerfd变为可读,而这个还是得通过前面的epoll来监听)。epoll的相关逻辑在前面的博客已经讲过了,故这里主要讲timerfd的逻辑。

epoll_reactor的定时器逻辑

先从timerfd的相关源码讲起。理所当然的,epoll_reactor里持有一个timerfd的描述符作为它的私有成员,这个描述符名叫timer_fd_。在epoll_reactor的构造函数中会调用epoll_reactor::do_timerfd_create(),这个函数将会完成timer_fd_的初始化,下面是这个函数的源码:

int epoll_reactor::do_timerfd_create()
{
   
  int fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);

  if (fd == -1 && errno == EINVAL)
  {
   
    fd = 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值