23

Linux定时器例子

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzUxMTk4MzY3MA%3D%3D&%3Bmid=2247484653&%3Bidx=1&%3Bsn=cea48e05c2099ac84d8fecdf38af91c9
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

点击上方蓝字可直接关注!方便下次阅读。如果对你有帮助,麻烦点个在看或点个赞,感谢~          文章首发   公众号—— 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、程序运行结果

3Ynq6nJ.png!mobile

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定时器例子”

MZzeIjR.png!mobile


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK