seo 发表于 2022-5-31 13:30:46

timerfd与epoll

timerfd与epoll发布时间:2022/5/31 13:13:16
            
                                                       
                                                       
            
      
      
               
                  linux timerfd系列函数总结
网上关于timerfd的文章很多,在这儿归纳总结一下方便以后使用,顺便贴出一个timerfd配合epoll使用的简单例子

一、timerfd系列函数

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

(1)timerfd_create()函数

https://common.cnblogs.com/images/copycode.gif

#include
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将被系统自动关闭,表示不传递)
*/
https://common.cnblogs.com/images/copycode.gif

(2)timerfd_settime()函数

https://common.cnblogs.com/images/copycode.gif

1 #include
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 */
https://common.cnblogs.com/images/copycode.gif

(3)timerfd_gettime()函数

https://common.cnblogs.com/images/copycode.gif

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 */
https://common.cnblogs.com/images/copycode.gif

1 uint64_t exp = 0;
2 read(fd, &exp, sizeof(uint64_t));
3 //可以用read函数读取计时器的超时次数,改值是一个8字节无符号的长整型
(4)下面贴出一个timerfd配合epoll函数的简单例子

https://common.cnblogs.com/images/copycode.gif

1 /********************************************************
2 * Filename: timerfd.c
3 * Author: zhangwj
4 * Desprition: a sample program of timerfd
5 * Date: 2017-04-17
6 * Warnning:
7 ********************************************************/
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16
17 #if 0
18 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 #endif
28
29 #define EPOLL_LISTEN_CNT      256
30 #define EPOLL_LISTEN_TIMEOUT    500
31
32 #define LOG_DEBUG_ON 1
33
34 #ifdef LOG_DEBUG_ON
35 #define LOG_DEBUG(fmt, args...) \
36   do {\
37         printf(":");\
38         printf(fmt "\n", ##args); \
39   } while(0);
40 #define LOG_INFO(fmt, args...) \
41   do { \
42         printf(":");\
43         printf(fmt "\n", ##args); \
44   } while(0);
45 #define LOG_WARNING(fmt, args...) \
46   do { \
47         printf(":");\
48         printf(fmt "\n", ##args); \
49   } while(0);
50 #else
51 #define LOG_DEBUG(fmt, args...)
52 #define LOG_INFO(fmt, args...)
53 #define LOG_WARNING(fmt, args...)
54 #endif
55 #define LOG_ERROR(fmt, args...) \
56   do{ \
57         printf(":");\
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 %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
               
      
      
   
            
      
      
https://www.yilongzhijia.cn/tupian/seo365t.jpg
页: [1]
查看完整版本: timerfd与epoll