简介:将一个文件描述符timerfd绑定到Channel上,Channel设置一个回调函数timeout()。EventLoop 监听timerfd。定时器开始计时。当定时器超时后,将会激活timerfd,然后Channel会调用timeout()。整个过程就是这样。
#include <muduo/net/EventLoop.h>
#include <muduo/net/Channel.h>
#include <sys/timerfd.h>
#include <boost/bind.hpp>
muduo::net::EventLoop *g_loop;
void timeout(){
printf("Timeout!\n");
g_loop->quit();
}
int main()
{
muduo::net::EventLoop loop;
g_loop = &loop;
int timerfd = ::timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); // CLOCK_MONOTONIC: 单调时间,表示系统启动后流逝的时间,由变量jiffies来记录的。
muduo::net::Channel channel(&loop, timerfd); // channel绑定到timerfd上
channel.setReadCallback(boost::bind(timeout)); // 此处必须用bind形式
channel.enableReading(); // 此处必须开启
struct itimerspec howlong;
/*
struct itimerspec
{
struct timespec it_interval; // Timer interval(timer循环时间间隔)
struct timespec it_value; // Initial expiration(timer初次到期时间间隔)
};
参考:https://www.cnblogs.com/LubinLew/p/POSIX-DataStructure.html
*/
bzero(&howlong, sizeof (howlong));
howlong.it_value.tv_sec = 1; // 设置超时时间
::timerfd_settime(timerfd, 0, &howlong, NULL); // 开始计时。超时就激活timerfd
/*
int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value);
13
14 timerfd_settime()此函数用于设置新的超时时间,并开始计时,能够启动和停止定时器;
15 fd: 参数fd是timerfd_create函数返回的文件句柄
16 flags:参数flags为1代表设置的是绝对时间(TFD_TIMER_ABSTIME 表示绝对定时器);为0代表相对时间。
17 new_value: 参数new_value指定定时器的超时时间以及超时间隔时间
18 old_value: 如果old_value不为NULL, old_vlaue返回之前定时器设置的超时时间,具体参考timerfd_gettime()函数
19
20 ** it_interval不为0则表示是周期性定时器。
21 it_value和it_interval都为0表示停止定时器
22
参考:https://www.cnblogs.com/wenqiang/p/6698371.html
*/
loop.loop();
::close(timerfd);
return 0;
}
参考《Linux多线程服务端编程》