linux centos timer_create接口
参考: https://www.cnblogs.com/muyi23333/articles/13523251.html https://blog.51cto.com/u_15352922/3745226 https://blog.csdn.net/weixin_34145418/article/details/116968058
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <pthread.h> 6 #include <signal.h> 7 #include <time.h> 8 #include <sys/timeb.h> 9 #include <sys/times.h> 10 11 12 13 #define xxxx_print_ln(log_level, fmt, ...) do { printf("(%s|%d)" fmt "\r\n", __func__, __LINE__, ##__VA_ARGS__); fflush(stdout);} while(0) 14 15 typedef void (*F_TIMER_CB)(void *); 16 17 18 void xxxx_timer_delete(void *timerid); 19 20 typedef struct _T_TIMER_ARG 21 { 22 F_TIMER_CB timer_cb; 23 void *arg; 24 void *timerid; 25 int is_onlyOnce; 26 }T_TIMER_ARG; 27 28 29 /***************************************************************** 30 31 定时器接口(第0套): 启动定时器 32 33 参数 : timerid, 定时器句柄 34 deleay_ms, 触发时间(ms) 35 interval_ms, 周期触发间隔(ms) 36 37 return : 非NULL, 成功, 返回定时器句柄 38 NULL, 失败 39 40 *****************************************************************/ 41 static int xxxx_timer_start(void *timerid, size_t deleay_ms, size_t interval_ms) 42 { 43 struct itimerspec it; 44 45 it.it_value.tv_sec = deleay_ms / 1000; 46 it.it_value.tv_nsec = (deleay_ms % 1000) * 1000 * 1000; 47 48 it.it_interval.tv_sec = interval_ms / 1000; 49 it.it_interval.tv_nsec = (interval_ms % 1000) * 1000 * 1000; 50 51 if (0 != timer_settime((timer_t)timerid, 0, &it, NULL)) { 52 return -1; 53 } 54 55 return 0; 56 } 57 58 static void xxxx_timer_thread(union sigval sig_v) 59 { 60 T_TIMER_ARG *timer_arg = NULL; 61 62 timer_arg = (T_TIMER_ARG *)sig_v.sival_ptr; 63 64 if (NULL == timer_arg) { 65 xxxx_print_ln(xxxx_ERROR, "timer_arg is no-valid"); 66 return ; 67 } 68 69 if (NULL != timer_arg->timer_cb) { 70 timer_arg->timer_cb(timer_arg->arg); 71 } 72 73 if (timer_arg->is_onlyOnce) { 74 xxxx_timer_delete(timer_arg->timerid); 75 timer_arg->timerid = 0; 76 } 77 } 78 79 /***************************************************************** 80 81 定时器接口(第0套): 创建定时器 82 83 参数 : 84 is_onlyOnce, 1仅一次(结束后句柄自动被删除), 0周期性定时器 85 timer_cb, 回调函数 86 arg, 回调函数的参数 87 88 return : 非NULL, 成功, 返回定时器句柄 89 NULL, 失败 90 91 *****************************************************************/ 92 static void *xxxx_timer_create(int is_onlyOnce, F_TIMER_CB timer_cb, void *arg) 93 { 94 timer_t timerid; 95 struct sigevent evp; 96 T_TIMER_ARG *timer_arg = NULL; 97 98 /* 99 参考: https://www.cnblogs.com/muyi23333/articles/13523251.html 100 https://blog.51cto.com/u_15352922/3745226 101 https://blog.csdn.net/weixin_34145418/article/details/116968058 102 */ 103 104 timer_arg = (T_TIMER_ARG *)calloc(1, sizeof(T_TIMER_ARG)); 105 if (NULL == timer_arg) { 106 xxxx_print_ln(xxxx_ERROR, "malloc failed(size=%u)", sizeof(T_TIMER_ARG)); 107 return NULL; 108 } 109 110 timer_arg->arg = arg; 111 timer_arg->timer_cb = timer_cb; 112 timer_arg->is_onlyOnce = (is_onlyOnce) ? 1 : 0; 113 114 memset(&evp, 0, sizeof(struct sigevent)); 115 116 evp.sigev_value.sival_ptr = (void *)timer_arg; 117 evp.sigev_notify = SIGEV_THREAD; // 线程通知的方式,派驻新线程 118 evp.sigev_notify_function = xxxx_timer_thread; 119 120 if (0 != timer_create(CLOCK_REALTIME, &evp, &timerid)) { 121 return NULL; 122 } 123 timer_arg->timerid = (void *)timerid; 124 125 return (void *)timerid; 126 } 127 128 /***************************************************************** 129 130 定时器接口(第0套): 删除定时器 131 132 参数 : timerid, 定时器句柄 133 deleay_ms, 触发时间(ms) 134 interval_ms, 周期触发间隔(ms) 135 136 return : 非NULL, 成功, 返回定时器句柄 137 NULL, 失败 138 139 *****************************************************************/ 140 void xxxx_timer_delete(void *timerid) 141 { 142 if (NULL == timerid) { 143 return; 144 } 145 146 // 同一个timerid, 多次重复删除, 不会引起崩溃 147 timer_delete((timer_t)timerid); 148 149 xxxx_print_ln(xxxx_INFO, "timer deleted (timerid=%x)", timerid); 150 151 return ; 152 } 153 154 /***************************************************************** 155 156 定时器接口(第一套): 创建一次性定时器 157 158 参数 : 159 deleay_ms, 触发时间(ms) 160 timer_cb, 回调函数 161 arg, 回调函数的参数 162 163 return : 非NULL, 成功, 返回定时器句柄 164 NULL, 失败 165 166 *****************************************************************/ 167 void *xxxx_timer_once(size_t deleay_ms, F_TIMER_CB timer_cb, void *arg) 168 { 169 void *timerid = NULL; 170 int ret = 0; 171 172 timerid = xxxx_timer_create(1, timer_cb, arg); 173 if (NULL == timerid) { 174 return NULL; 175 } 176 177 ret = xxxx_timer_start(timerid, deleay_ms, 0); 178 179 return (0 == ret )? timerid : NULL; 180 } 181 182 /***************************************************************** 183 184 定时器接口(第二套): 创建重复性定时器 185 186 参数 : 187 deleay_ms, 触发时间(ms) 188 interval_ms, 周期触发间隔(ms) 189 timer_cb, 回调函数 190 arg, 回调函数的参数 191 192 return : 非NULL, 成功, 返回定时器句柄 193 NULL, 失败 194 195 *****************************************************************/ 196 void *xxxx_timer_interval(size_t deleay_ms, size_t interval_ms, F_TIMER_CB timer_cb, void *arg) 197 { 198 void *timerid = NULL; 199 int ret = 0; 200 201 timerid = xxxx_timer_create(0, timer_cb, arg); 202 if (NULL == timerid) { 203 return NULL; 204 } 205 206 ret = xxxx_timer_start(timerid, deleay_ms, interval_ms); 207 208 return (0 == ret ) ? timerid : NULL; 209 }
/**************************************** 返回当前时间字符串 格式为20211223_160548_054 参数 : 无 return : 非NULL, 当前时间字符串, 需要释放 ****************************************/ char *xxxx_get_time_stamp(void) { char *time_stamp_out = NULL; time_t ltime; struct tm *today; struct timeb timebuffer; time( <ime ); today = localtime( <ime ); ftime( &timebuffer); asprintf(&time_stamp_out, "%04d%02d%02d_%02d%02d%02d_%03d", 1900 + today->tm_year, today->tm_mon + 1, today->tm_mday, today->tm_hour, today->tm_min, today->tm_sec, timebuffer.millitm); return time_stamp_out; } void t_cb(void *arg) { printf("%s\r\n", arg); printf("%s\r\n", xxxx_get_time_stamp()); } int main(int argc, char *argv) { void *h = NULL; printf("%s\r\n", xxxx_get_time_stamp()); #if 0 h = xxxx_timer_once(2600, t_cb, "thanks!!!"); sleep(5); xxxx_timer_delete(h); sleep(5); #else h = xxxx_timer_interval(2897, 5897, t_cb, "thanks!!!"); sleep(30); xxxx_timer_delete(h); sleep(30); #endif return 0; }
gcc my_timer.c my_timer_test.c -lrt -o a.out ; ./a.out