Linux的timerfd

timerfdLinux爲用戶程序提供的一個定時器接口。這個接口基於文件描述符,因此可以被用於select/poll的應用場景。 node

1.      使用方法

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

此函數用於設置新的超時時間,並開始計時。

參數ufdtimerfd_create返回的文件句柄。

參數flags1表明設置的是絕對時間;爲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

pollclose與標準文件操做相同。

2.      內核實現

timerfd的內核實現代碼在kernel/fs/timerfd.c,它的實現基於Linuxhrtimer

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_fopsanno_inode_getfd是文件系統anon_inodefs的一個幫助函數。anon文件系統比較簡單,整個文件系統只有一個inode節點,其實現代碼能夠在fs/anon_inodes.c中找到。

timerfd_settime的實現

timerfd_settime最終會調用hrtimer_start啓動定時器,其超時函數被設置爲timerfd_tmrproc

timerfd_tmrproc

timefd_tmrproctimerfd的定時器超時函數。在timerfd超時時,該函數會設置定時器超時標記位;增長定時器超時次數(在設置定時器循環模式時,可能會出現屢次超時沒有被處理的狀況);喚醒一個等待隊列,從而喚醒可能存在的正被阻塞的readselect

timerfd_fops

static const struct file_operations timerfd_fops = {

       .release    = timerfd_release,

       .poll        = timerfd_poll,

       .read              = timerfd_read,

};

timerfd_read函數是文件操做read的內核實現,讀到的是定時器的超時次數。該函數在阻塞模式下會把自身掛到timerfd的等待隊列中,等待定時器超時時被喚醒。

timerfd_polltimerfd的等待隊列登記到一個poll_table,從而在定時器超時時能喚醒select系統調用。

timerfd_release

timerfd_release函數釋放timerfd_create函數中申請的資源,刪除已分配的定時器。

相關文章
相關標籤/搜索