大家好,欢迎来到IT知识分享网。
点击上方蓝字可直接关注!方便下次阅读。如果对你有帮助,麻烦点个在看或点个赞,感谢~ 文章首发 公众号—— Pou光明
程序中难免会使用到定时器,今天给大家介绍Linux中一种定时器的实现。Linux下还有很多其他定时的实现,如精确定时等,感兴趣的同志可以再做深入了解。
编程到现在,其实很多工作都是在调用api,还没能完全脱离面向“谷歌”编程的实质,面对这种情形,如何破局呢?好巧啊,我也在思考。。。。。。
一、api简介
NAME
timerfd_create, timerfd_settime, timerfd_gettime -通过文件描述符来告知定时器状态。
SYNOPSIS
#include <sys/timerfd.h>
int timerfd_create(int clockid, int flags);
int timerfd_settime(int fd, int flags,
const struct itimerspec *new_value,
struct itimerspec *old_value);
int timerfd_gettime(int fd, struct itimerspec *curr_value);
timerfd_create()
创建一个新的计时器对象,并返回对应的文件描述符。 clockid参数指定用于标记计时器进度的时钟,并且必须为CLOCK_REALTIME或CLOCK_MONOTONIC。CLOCK_REALTIME是可设置的系统范围时钟。CLOCK_MONOTONIC是不可设置的时钟。具体区别,感兴趣的同志自行验证。
timerfd_settime()
启动或关闭定时器。
new_value参数指定计时器的初始到期时间和间隔。用于此参数的itimer结构包含两个字段,每个字段依次是timespec类型的结构:
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 */
};
二、用例及封装函数
1、 根据时间间隔创建定时器
static int32_t TimerStart(uint64_t interval_ms)
{
int32_t timerfd = 0;
struct itimerspec its = {0};
struct itimerspec itsTest = {0};
timerfd = timerfd_create(CLOCK_MONOTONIC, 0);
if (timerfd < 0)
{
return -1;
}
/* Start the timer */
its.it_value.tv_sec = interval_ms / 1000;
its.it_value.tv_nsec = (interval_ms % 1000) * 1000000;
its.it_interval = its.it_value;
// if (timerfd_settime(timerfd, 0, &its, NULL) < 0)
if (timerfd_settime(timerfd, TFD_TIMER_ABSTIME, &its, NULL) < 0)
{
close(timerfd);
return -1;
}
return timerfd;
}
2、通过文件描述符判断定时器是否溢出
static int32_t TimerExpired(int32_t timerfd)
{
uint64_t exp;
ssize_t s;
s = read(timerfd, &exp, sizeof(uint64_t));
if (s != sizeof(uint64_t))
{
printf("read timerd failed \n");
return -1;
}
return 0;
}
3、通过文件描述符销毁定时器
static void TimerStop(int32_t timerfd)
{
close(timerfd);
}
4、主测试程序
int main(void)
{
int test = 1;
struct itimerspec curr_value = {0};
int32_t l_n32TimerFd = TimerStart(1100);
printf("l_n32TimerFd is %d \n", l_n32TimerFd);
while (1)
{
test++;
if (-1 == TimerExpired(l_n32TimerFd))
{
printf("timer failed !\n");
TimerStop(l_n32TimerFd);
}
timerfd_gettime(l_n32TimerFd, &curr_value);
// printf("curr_value is %ld \n", curr_value.it_value.tv_sec);
printf("curr_value nsec is %ld \n", curr_value.it_value.tv_nsec);
DEBUG("time is arrive 1s count is %d ", test);
if (5 == test)
{
struct itimerspec its = {0};
/* Stop the timer */
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 0;
its.it_interval = its.it_value;
if (timerfd_settime(l_n32TimerFd, TFD_TIMER_ABSTIME, &its, NULL) < 0)
{
close(l_n32TimerFd);
printf("timerfd_settime ailed \n");
return -1;
}
}
}
}
5、程序运行结果
6、更多第一手英文资料的获取
man timerfd_create
很多我就是翻译了一下。
三、总结时间
如何理解马克思主义哲学中的对立统一 。。。
再增加一个时间戳的调用:
struct timespec t_start, t_end;
unsigned long total_us = 0;
clock_gettime(CLOCK_MONOTONIC, &t_start);
// do some
clock_gettime(CLOCK_MONOTONIC, &t_end);
total_us = (t_end.tv_sec - t_start.tv_sec) * 1000000 + (t_end.tv_nsec - t_start.tv_nsec) / 1000;
DEBUG("time is arrive 1s count is %d %lu us", test, total_us );
获取工程源码可在程序后台留言:“Linux定时器例子”
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/20655.html