linux timerfd系列函数总结

网上关于timerfd的文章很多,在这儿归纳总结一下方便以后使用,顺便贴出一个timerfd配合epoll使用的简单例子

一、timerfd系列函数

  timerfd是Linux为用户程序提供的一个定时器接口。这个接口基于文件描述符,通过文件描述符的可读事件进行超时通知,因此可以配合select/poll/epoll等使用。
下面对timerfd系列函数先做一个简单的介绍:

(1)timerfd_create()函数

#include <sys/timerfd.h>int timerfd_create(int clockid, int flags);
/*
timerfd_create()函数创建一个定时器对象,同时返回一个与之关联的文件描述符。
clockid:clockid标识指定的时钟计数器,可选值(CLOCK_REALTIME、CLOCK_MONOTONIC。。。)
CLOCK_REALTIME:系统实时时间,随系统实时时间改变而改变,即从UTC1970-1-1 0:0:0开始计时,中间时刻如果系统时间被用户改成其他,则对应的时间相应改变
CLOCK_MONOTONIC:从系统启动这一刻起开始计时,不受系统时间被用户改变的影响
flags:参数flags(TFD_NONBLOCK(非阻塞模式)/TFD_CLOEXEC(表示当程序执行exec函数时本fd将被系统自动关闭,表示不传递)
*/

(2)timerfd_settime()函数

 1 #include <sys/timerfd.h>2 3 struct timespec {4     time_t tv_sec;                /* Seconds */5     long   tv_nsec;               /* Nanoseconds */6 };7 8 struct itimerspec {9     struct timespec it_interval;  /* Interval for periodic timer (定时间隔周期)*/
10     struct timespec it_value;     /* Initial expiration (第一次超时时间)*/
11 };
12 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 */

(3)timerfd_gettime()函数

1 int timerfd_gettime(int fd, struct itimerspec *curr_value);
2 /*
3     timerfd_gettime()函数获取距离下次超时剩余的时间
4     curr_value.it_value 字段表示距离下次超时的时间,如果改值为0,表示计时器已经解除
5     改字段表示的值永远是一个相对值,无论TFD_TIMER_ABSTIME是否被设置
6     curr_value.it_interval 定时器间隔时间
7 */

1 uint64_t exp = 0;
2 read(fd, &exp, sizeof(uint64_t));
3 //可以用read函数读取计时器的超时次数,改值是一个8字节无符号的长整型

(4)下面贴出一个timerfd配合epoll函数的简单例子

  1 /********************************************************2 * Filename: timerfd.c3 * Author: zhangwj4 * Desprition: a sample program of timerfd5 * Date: 2017-04-176 * Warnning:7 ********************************************************/8 #include <stdio.h>9 #include <stdint.h>10 #include <string.h>11 #include <stdlib.h>12 #include <pthread.h>13 #include <errno.h>14 #include <sys/epoll.h>15 #include <sys/timerfd.h>16 17 #if 018 struct timespec {19     time_t tv_sec;                /* Seconds */20     long   tv_nsec;               /* Nanoseconds */21 };22 23 struct itimerspec {24     struct timespec it_interval;  /* Interval for periodic timer */25     struct timespec it_value;     /* Initial expiration */26 };27 #endif28 29 #define EPOLL_LISTEN_CNT        25630 #define EPOLL_LISTEN_TIMEOUT    50031 32 #define LOG_DEBUG_ON 133 34 #ifdef LOG_DEBUG_ON 35 #define LOG_DEBUG(fmt, args...) \36     do {  \37         printf("[DEBUG]:");\38         printf(fmt "\n", ##args); \39     } while(0);40 #define LOG_INFO(fmt, args...) \41     do { \42         printf("[INFO]:");\43         printf(fmt "\n", ##args); \44     } while(0);45 #define LOG_WARNING(fmt, args...) \46     do { \47         printf("[WARNING]:");\48         printf(fmt "\n", ##args); \49     } while(0);50 #else51 #define LOG_DEBUG(fmt, args...) 52 #define LOG_INFO(fmt, args...) 53 #define LOG_WARNING(fmt, args...) 54 #endif55 #define LOG_ERROR(fmt, args...) \56     do{ \57         printf("[ERROR]:");\58         printf(fmt "\n", ##args);\59     }while(0);60 61 #define handle_error(msg) \62         do { perror(msg); exit(EXIT_FAILURE); } while (0)63 64 static int g_epollfd = -1;65 static int g_timerfd = -1;66 uint64_t tot_exp = 0;67 68 static void help(void)69 {70     exit(0);71 }72 73 static void print_elapsed_time(void)74 {75     static struct timespec start;76     struct timespec curr;77     static int first_call = 1;78     int secs, nsecs;79     80     if (first_call) {81         first_call = 0;82         if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) 83             handle_error("clock_gettime");84     }   85     86     if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) 87         handle_error("clock_gettime");88     89     secs = curr.tv_sec - start.tv_sec;90     nsecs = curr.tv_nsec - start.tv_nsec;91     if (nsecs < 0) {92         secs--;93         nsecs += 1000000000;94     }   95     printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000);96 }97 98 void timerfd_handler(int fd)99 {
100     uint64_t exp = 0;
101
102     read(fd, &exp, sizeof(uint64_t));
103     tot_exp += exp;
104     print_elapsed_time();
105     printf("read: %llu, total: %llu\n", (unsigned long long)exp, (unsigned long long)tot_exp);
106
107     return;
108 }
109
110 void epoll_event_handle(void)
111 {
112     int i = 0;
113     int fd_cnt = 0;
114     int sfd;
115     struct epoll_event events[EPOLL_LISTEN_CNT];
116
117     memset(events, 0, sizeof(events));
118     while(1)
119     {
120         /* wait epoll event */
121         fd_cnt = epoll_wait(g_epollfd, events, EPOLL_LISTEN_CNT, EPOLL_LISTEN_TIMEOUT);
122         for(i = 0; i < fd_cnt; i++)
123         {
124             sfd = events[i].data.fd;
125             if(events[i].events & EPOLLIN)
126             {
127                 if (sfd == g_timerfd)
128                 {
129                     timerfd_handler(sfd);
130                 }
131             }
132         }
133     }
134 }
135
136 int epoll_add_fd(int fd)
137 {
138     int ret;
139     struct epoll_event event;
140
141     memset(&event, 0, sizeof(event));
142     event.data.fd = fd;
143     event.events = EPOLLIN | EPOLLET;
144
145     ret = epoll_ctl(g_epollfd, EPOLL_CTL_ADD, fd, &event);
146     if(ret < 0) {
147         LOG_ERROR("epoll_ctl Add fd:%d error, Error:[%d:%s]", fd, errno, strerror(errno));
148         return -1;
149     }
150
151     LOG_DEBUG("epoll add fd:%d--->%d success", fd, g_epollfd);
152     return 0;
153 }
154
155 int epollfd_init()
156 {
157     int epfd;
158
159     /* create epoll fd */
160     epfd = epoll_create(EPOLL_LISTEN_CNT);
161     if (epfd < 0) {
162         LOG_ERROR("epoll_create error, Error:[%d:%s]", errno, strerror(errno));
163         return -1;
164     }
165     g_epollfd = epfd;
166     LOG_DEBUG("epoll fd:%d create success", epfd);
167
168     return epfd;
169 }
170
171 int timerfd_init()
172 {
173     int tmfd;
174     int ret;
175     struct itimerspec new_value;
176
177     new_value.it_value.tv_sec = 2;
178     new_value.it_value.tv_nsec = 0;
179     new_value.it_interval.tv_sec = 1;
180     new_value.it_interval.tv_nsec = 0;
181
182     tmfd = timerfd_create(CLOCK_MONOTONIC, 0);
183     if (tmfd < 0) {
184         LOG_ERROR("timerfd_create error, Error:[%d:%s]", errno, strerror(errno));
185         return -1;
186     }
187
188     ret = timerfd_settime(tmfd, 0, &new_value, NULL);
189     if (ret < 0) {
190         LOG_ERROR("timerfd_settime error, Error:[%d:%s]", errno, strerror(errno));
191         close(tmfd);
192         return -1;
193     }
194
195     if (epoll_add_fd(tmfd)) {
196         close(tmfd);
197         return -1;
198     }
199     g_timerfd = tmfd;
200
201     return 0;
202 }
203
204 int main(int argc, char **argv)
205 {
206     if (epollfd_init() < 0) {
207         return -1;
208     }
209
210     if (timerfd_init()) {
211         return -1;
212     }
213
214     /* event handle */
215     epoll_event_handle();
216
217     return 0;
218 }

timerfd与epoll相关推荐

  1. 深入理解 Linux 的 epoll 机制

    坚持思考,就会很酷 在 Linux 系统之中有一个核心武器:epoll 池,在高并发的,高吞吐的 IO 系统中常常见到 epoll 的身影. IO 多路复用 在 Go 里最核心的是 Goroutine ...

  2. linux timerfd系列函数总结:timerfd.h

    Table of Contents 一.timerfd系列函数 (1)timerfd_create()函数 (2)timerfd_settime()函数 (3)timerfd_gettime()函数 ...

  3. SurfaceFlinger模块-VSYNC研究

    Vsync信号是SurfaceFlinger进程中核心的一块逻辑,我们主要从以下几个方面着手讲解. 软件Vsync是怎么实现的,它是如何保持有效性的? systrace中看到的VSYNC信号如何解读, ...

  4. Linux下 timerfd创建定时器并使用 epoll 监听

    介绍:Linux系统提供了timerfd系列的定时函数,其具体函数名如下 #include <sys/timerfd.h>int timerfd_create(int clockid, i ...

  5. eventfd和timerfd

    在学习muduo中有看到eventfd和timerfd这2个函数,它们都可以通过文件描述符操作,能够很好的与epoll结合.        eventfd用来在进程或线程之间通信,接口如下:     ...

  6. Linux环境编程 用户层定时器使用一 timerfd的使用

    timerfd是linux提供的定时器机制,基于文件描述符,定时器精度最高可达纳秒级别,接口包括定时器创建.启动定时器.关闭定时器和删除定时器.下面介绍一下timerfd  API接口和一个结合epo ...

  7. timerfd API使用总结

    timerfd 介绍 timerfd 是在Linux内核2.6.25版本中添加的接口,其是Linux为用户提供的一个定时器接口.这个接口基于文件描述符,所以可以被用于select/poll/epoll ...

  8. linux新的API signalfd、timerfd、eventfd使用说明

    三种新的fd加入linux内核的的版本: signalfd:2.6.22 timerfd:2.6.25 eventfd:2.6.22 三种fd的意义: signalfd:传统的处理信号的方式是注册信号 ...

  9. Linux环境SOCKET编程5:定时器接口timerfd

    1.概述 timerfd是Linux为用户程序提供的一个定时器接口.这个接口基于文件描述符,通过文件描述符的可读事件进行超时通知,所以能够被用于select/poll的应用场景.timerfd是lin ...

最新文章

  1. python定制框架知识点_我的第一个python web开发框架(25)——定制ORM(一)
  2. IBM copy service--flashcopy 实验
  3. ubuntu 16.10安装mysql_在Ubuntu 16.10安装mysql workbench报未安装软件包 libpng12-0错误的解决方法...
  4. mac mysql
  5. JAVA复习(对象的克隆、正则表达式)
  6. 工作107:插入请求头
  7. Android 获取天气数据
  8. 【福利】爱德华·阿什福德·李:人类与AI技术将是共生关系
  9. httpcline转发_go http请求转发
  10. 太原警方通过微博提醒您手机丢失如何保微信安全
  11. 单元测试中简单使用Mockito解决Spring Bean依赖树问题
  12. JavaScript中对于函数的形参实参个数匹配是如何做的?
  13. QT 实现采集即时音频信号并发送至另一台电脑播放
  14. 一个简单的互斥量与条件变量例子
  15. 十六进制转十进制_跟运维组学Python之秒懂十六进制
  16. oracle优化器analyzed,Oracle Optimizer:迁移到使用基于成本的优化器—–系列1.2-数据库专栏,ORACLE...
  17. 【笨嘴拙舌WINDOWS】Dj,oh!nonono,It is about DC
  18. 3.Go语言中常量,变量, 及其命名规则以及代码风格
  19. [SilkyBible] XviD系列-9
  20. el-input输入字母转化大写字母

热门文章

  1. file_get_content和curl的性能比较
  2. UVa 11468 (AC自动机 概率DP) Substring
  3. 替换Quartus 自带编辑器 (转COM张)
  4. hujingwei oracle_Oracle收缩表空间
  5. oracle安装出现getproces,oracle安装问题
  6. unity 删除服务器项目,在吗?有个支持批量构建项目的好东西推荐给你
  7. php判断记录,PHP判断数据库中的记录是否存在的方法,php数据库_PHP教程
  8. 物资管理系统c语言课程设计,C语言实现仓库物资管理系统
  9. python3怎么创建文件_Python3.5 创建文件的简单实例
  10. Win32ASM学习[10]:传送指令