Linux环境编程 用户层定时器使用一 timerfd的使用
生活随笔
收集整理的這篇文章主要介紹了
Linux环境编程 用户层定时器使用一 timerfd的使用
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
timerfd是linux提供的定時器機(jī)制,基于文件描述符,定時器精度最高可達(dá)納秒級別,接口包括定時器創(chuàng)建、啟動定時器、關(guān)閉定時器和刪除定時器。下面介紹一下timerfd? API接口和一個結(jié)合epoll使用的定時器demo。
1. 創(chuàng)建定時器?
#include <sys/timerfd.h> /** 功能 : 創(chuàng)建定時器* 返回值:成功返回定時器文件描述符,失敗返回-1* 參數(shù):? clockid可以是CLOCK_REALTIME(實(shí)時時鐘)或者CLOCK_MONOTONIC(遞增時鐘),實(shí)時時鐘可以被系統(tǒng)時間改變,后者不會。* 如果這里使用實(shí)時時鐘,當(dāng)手動更改系統(tǒng)時間定時器也會受影響,而遞增時鐘則只受設(shè)置的時間值影響。* flags : 可選項包括TFD_NONBLOCK(非阻塞)和TFD_CLOEXEC,阻塞指的是當(dāng)定時器未超時的時候,如果調(diào)用read(timerfd)會阻塞直*? 到定時器超時,如果設(shè)置TFD_NONLOCK,則會直接返回并返回-1. 這與套接字描述符類似。*/ int timerfd_create(int clockid, int flags); 如果這里使用實(shí)時時鐘,當(dāng)手動更改系統(tǒng)時間定時器也會受影響,而遞增時鐘則只受設(shè)置的時間值影響。* flags : 可選項包括TFD_NONBLOCK(非阻塞)和TFD_CLOEXEC,阻塞指的是當(dāng)定時器未超時的時候,如果調(diào)用read(timerfd)會阻塞直*? 到定時器超時,如果設(shè)置TFD_NONLOCK,則會直接返回并返回-1. 這與套接字描述符類似。*/ int timerfd_create(int clockid, int flags);2. 啟動和停止定時器
/** 功能 定時器啟動和關(guān)閉* 返回值 : 成功返回0,失敗返回-1,并存儲錯誤碼到errno* 參數(shù): fd: 定時器描述符* flags: 0 或者TFD_TIMER_ABSTIME,0代表相對時間,即相對于當(dāng)前時間多少,后者是絕對時間。* new_value: 當(dāng)new_value.it_value非0時,用于設(shè)置定時器第一次超時時間,為0代表停止定時器new_value.it_interval:表示第一次超時后下一次超時的時間,為0代表定時器只超時一次* old_value: 如果不為NULL,則用來存儲當(dāng)前時間。int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value);3. 關(guān)閉定時器
/** 功能: 和普通描述符一樣,用完后使用close釋放* 參數(shù):timerfd為timerfd_create()創(chuàng)建的定時器描述符*/ close(timerfd);4. 時間結(jié)構(gòu)體
struct timespec {time_t tv_sec; /* Seconds */long tv_nsec; /* Nanoseconds */ };struct itimerspec {struct timespec it_interval; /* Interval for periodic timer */struct timespec it_value; /* Initial expiration */ };下面是一個結(jié)合epoll使用的定時器demo,創(chuàng)建一個每隔2s超時的定時器并加入到epoll監(jiān)聽隊列中,每當(dāng)定時器到期超時時產(chǎn)生一個讀事件,之后可以去執(zhí)行相應(yīng)的定時器回調(diào)函數(shù)。
/** Description : linux 應(yīng)用層編程之定時器timerfd的使用* Date :20180611* Author :mason* Mail : mrsonko@126.com**/#include <sys/timerfd.h> #include <sys/epoll.h> #include <unistd.h> #include <stdlib.h> #include <stdint.h> #include <stdio.h> #include<errno.h> #include <time.h>#define TIME_MAX 2 #define log(fmt, arg...) printf(""fmt, ##arg)void main() {int tfd; //定時器描述符int efd; //epoll描述符int fds, ret;uint64_t value;struct epoll_event ev, *evptr;struct itimerspec time_intv; //用來存儲時間tfd = timerfd_create(CLOCK_MONOTONIC, 0); //創(chuàng)建定時器if(tfd == -1) {log("create timer fd fail \r\n");return ;}time_intv.it_value.tv_sec = TIME_MAX; //設(shè)定2s超時time_intv.it_value.tv_nsec = 0;time_intv.it_interval.tv_sec = time_intv.it_value.tv_sec; //每隔2s超時time_intv.it_interval.tv_nsec = time_intv.it_value.tv_nsec;log("timer start ...\n");timerfd_settime(tfd, 0, &time_intv, NULL); //啟動定時器efd = epoll_create1(0); //創(chuàng)建epoll實(shí)例if (efd == -1) {log("create epoll fail \r\n");close(tfd);return ;}evptr = (struct epoll_event *)calloc(1, sizeof(struct epoll_event));if (evptr == NULL) {log("epoll event calloc fail \r\n");close(tfd);close(efd);return ;}ev.data.fd = tfd; ev.events = EPOLLIN; //監(jiān)聽定時器讀事件,當(dāng)定時器超時時,定時器描述符可讀。epoll_ctl(efd, EPOLL_CTL_ADD, tfd, &ev); //添加到epoll監(jiān)聽隊列中while(1) {fds = epoll_wait(efd, evptr, 1, -1); //阻塞監(jiān)聽,直到有事件發(fā)生if(evptr[0].events & EPOLLIN){ ret = read(evptr->data.fd, &value, sizeof(uint64_t));if (ret == -1) log("read return -1, errno :%d \r\n", errno);elselog("*** timer up *** \n"); } }return ; }實(shí)驗截圖:
代碼路徑:
git@github.com:FuYuanDe/timerfd.git
參考資料:
https://linux.die.net/man/2/timerfd_create
總結(jié)
以上是生活随笔為你收集整理的Linux环境编程 用户层定时器使用一 timerfd的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么做镜像文件ghost Ghost制作
- 下一篇: 电脑怎么点关机重启电脑没反应了 电脑无法