timerfd是Linux爲用戶程序提供的一個定時器接口。這個接口基於文件描述符,因此可以被用於select/poll的應用場景。 node
timerfd提供了以下接口供用戶使用 函數
timerfd_create spa
int timerfd_create(int clockid, int flags); 指針
timerfd_create用於建立一個定時器文件。 orm
參數clockid能夠是CLOCK_MONOTONIC或者CLOCK_REALTIME。 接口
參數flags能夠是0或者O_CLOEXEC/O_NONBLOCK。 隊列
函數返回值是一個文件句柄fd。 資源
timerfd_settime get
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函數中申請的資源,刪除已分配的定時器。