900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Linux 环境编程 用户层定时器使用二 timer_create的使用

Linux 环境编程 用户层定时器使用二 timer_create的使用

时间:2021-01-21 19:35:07

相关推荐

Linux 环境编程 用户层定时器使用二 timer_create的使用

用户层定时器有两种,一种是timerfd,另一种是timer_create,前者比较新,使用比较方便。

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

/fuyuande/article/details/80658695

这里记录一下timer_create的用法。

先介绍一下相关接口,再结合一个简单的demo介绍一下使用

头文件:#include <signal.h>#include <time.h>/* * 创建定时器* 创建POSIX定时器,不会被传递给子进程。编译时候增加编译选项 -lrt* 定时器ID存储在timerid中,定时器ID在当前进程中是唯一的,除非定时器* 被删除。初始化的时候定时器未启动。* clockid定义了定时器计时的方法,有如下几个值:* CLOCK_REALTIME : 可设置的系统范围的实时时钟* CLOCK_MONOTONIC : 单调递增的时钟,系统启动后不会被改变* CLOCK_PROCESS_CPUTIME_ID : 用于测量当前进程(包括所有线程)CPU占用时间,包含用户调用和系统调用,* CLOCK_THREAD_CPUTIME_ID : 用于测量当前线程CPU占用时间,包含用户调用和系统调用* 参数sevp指出该如何通知调用者定时器超时信息,根据sevp.sigev_notify字段,该字段有如下值* SIGEV_NONE : 定时器超时后不使用异步通知,可能的情况是使用timer_gettime来监控定时器* SIGEV_SIGNAL : 一旦超时,产生一个信号,任何时候,至多只有一个信号会发送到队列里面,可以使用timer_getoverrun来获取超时次数* SIGEV_THREAD : 新建一个线程去处理,该线程执行sigev_notif_function为入口函数* SIGEV_THREAD_ID : linux独有,发出一个信号,和SIG_NAL类似,只不过该信号发送到指定的线程。* NULL : 如果sevp被设置为NULL,相当于SIGEV_SIGNAL,信号是SIGALRM* 返回值,成功返回0,失败返回-1并将错误码设置到errno里 */int timer_create(clockid_t clockid, struct sigevent *sevp, timer_t *timerid);使用到的时间参数数据结构体有下面两该个struct timespec {time_t tv_sec;/* Seconds */long tv_nsec;/* Nanoseconds */};struct itimerspec {struct timespec it_interval; /* Timer interval */struct timespec it_value;/* Initial expiration */};/** 启动/关闭定时器* itimerspec将时间分为秒和纳秒的组合* 如果参数new_value->it_value不为0,则启动定时器。如果定时器已经启动则覆盖之前的定时器设置* 如果参数new_value->it_value为0则关闭定时器。* 参数new_value->it_interval用于定时器重启的间隔,即当定时器超时后下一次超时的间隔。* 参数flags为0的话默认是相对时间,也可以使用TIMER_ABSTIME绝对时间* 成功返回0,失败返回-1,并设置errno*/int timer_settime(timer_t timerid, int flags, const struct itimerspec *new_value, struct itimerspec * old_value);/** 返回到下一次超时的时间间隔,如果返回0说明已经超时*/int timer_gettime(timer_t timerid, struct itimerspec *curr_value);/** 删除定时器* 成功返回0,失败返回-1并设置errno*/int timer_delete(timer_t timerid);

下面是一个简单例子,创建一个定时器,超时时间1s, 超时后发出信号,超时5次后程序退出

/** Description : Linux用户层定时器使用<二>定义一个每个1s触发的定时器,定时器触发后发出信号并打印,超过5次后程序自动退出。* Author: mason* Date : 08*/#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <signal.h>#include <time.h>#define EXPIRE_MAX 5static int expire_cnt;#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \} while (0)/* 定时器回调函数 */void timer_handler() { if (expire_cnt < EXPIRE_MAX){expire_cnt++;}printf("timer expire\r\n");return;} int main(int argc, char *argv[]){timer_t timerid;struct sigevent sev;struct itimerspec its;/* 注册信号回调函数 */sev.sigev_notify = SIGEV_SIGNAL;sev.sigev_signo = SIGUSR1;sev.sigev_value.sival_ptr = &timerid;signal(SIGUSR1, timer_handler);/* 创建定时器 */if (timer_create(CLOCK_MONOTONIC, &sev, &timerid) == -1){errExit("timer_create");}/* 设置定时器时间参数超时1s */its.it_value.tv_sec = 1;its.it_value.tv_nsec = 0;its.it_interval.tv_sec = its.it_value.tv_sec;its.it_interval.tv_nsec = its.it_value.tv_nsec;/* 启动定时器 */if (timer_settime(timerid, 0, &its, NULL) == -1){errExit("timer_settime");}/* 超时5次后退出 */while (expire_cnt != 5) {sleep(1);}/* 删除定时器 */timer_delete(timerid);exit(EXIT_SUCCESS);}

timer_create和timerfd相比的话,接口复杂,需要使用到信号机制,实际使用的话建议使用timerfd。

参考资料:

1. man timer_create:/man/2/timer_create

2.POSIX定时器:timer_settime()

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。