timerfd是Linux为用户程序提供的一个定时器接口。这个接口基于文件描述符,因此可以被用于select/poll的应用场景。node
timerfd提供了以下接口供用户使用函数
timerfd_createspa
int timerfd_create(int clockid, int flags);指针
timerfd_create用于建立一个定时器文件。orm
参数clockid能够是CLOCK_MONOTONIC或者CLOCK_REALTIME。接口
参数flags能够是0或者O_CLOEXEC/O_NONBLOCK。队列
函数返回值是一个文件句柄fd。资源
timerfd_settimeget
int timerfd_settime(int ufd, int flags, const struct itimerspec * utmr, struct itimerspec * otmr);it
此函数用于设置新的超时时间,并开始计时。
参数ufd是timerfd_create返回的文件句柄。
参数flags为1表明设置的是绝对时间;为0表明相对时间。
参数utmr为须要设置的时间。
参数otmr为定时器此次设置以前的超时时间。
函数返回0表明设置成功。
timerfd_gettime
int timerfd_gettime(int ufd, struct itimerspec * otmr);
此函数用于得到定时器距离下次超时还剩下的时间。若是调用时定时器已经到期,而且该定时器处于循环模式(设置超时时间时struct itimerspec::it_interval不为0),那么调用此函数以后定时器从新开始计时。
read
当timerfd为阻塞方式时,read函数将被阻塞,直到定时器超时。
函数返回值大于0,表明定时器超时;不然,表明没有超时(被信号唤醒,等等)。
poll/close
poll,close与标准文件操做相同。
timerfd的内核实现代码在kernel/fs/timerfd.c,它的实现基于Linux的hrtimer。
timerfd_create的实现
SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
l 作一些定时器的初始化工做
l 调用hrtimer_init初始化一个hrtimer
l 调用anon_inode_getfd分配一个dentry,并获得一个文件号fd,同时传入timerfd的文件操做指针struct file_operations timerfd_fops。anno_inode_getfd是文件系统anon_inodefs的一个帮助函数。anon文件系统比较简单,整个文件系统只有一个inode节点,其实现代码能够在fs/anon_inodes.c中找到。
timerfd_settime的实现
timerfd_settime最终会调用hrtimer_start启动定时器,其超时函数被设置为timerfd_tmrproc。
timerfd_tmrproc
timefd_tmrproc是timerfd的定时器超时函数。在timerfd超时时,该函数会设置定时器超时标记位;增长定时器超时次数(在设置定时器循环模式时,可能会出现屡次超时没有被处理的状况);唤醒一个等待队列,从而唤醒可能存在的正被阻塞的read、select。
timerfd_fops
static const struct file_operations timerfd_fops = {
.release = timerfd_release,
.poll = timerfd_poll,
.read = timerfd_read,
};
timerfd_read函数是文件操做read的内核实现,读到的是定时器的超时次数。该函数在阻塞模式下会把自身挂到timerfd的等待队列中,等待定时器超时时被唤醒。
timerfd_poll将timerfd的等待队列登记到一个poll_table,从而在定时器超时时能唤醒select系统调用。
timerfd_release
timerfd_release函数释放timerfd_create函数中申请的资源,删除已分配的定时器。