专栏首页Pou光明Linux定时器例子

Linux定时器例子

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

本文分享自微信公众号 - Pou光明(pou0230),作者:PouG

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-11-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • linux之shell综合例子之定时任务

    西西嘛呦
  • linux中定时任务的格式及例子

    逐梦的青春
  • Linux高精度定时器hrtimer使用实例

    随着内核不断更新演进,内核对定时器的分辨率要求越来越高。硬件的高速发展也逐渐能够满足内核的这一要求,因此内核针对硬件提供的便利,开始设计了更高分辨率的定时器(h...

    开源519
  • Linux定时任务实例

    备份/etc/hosts,/etc/rc.local,/var/spool/cron/crontabs/root文件,以压缩包形式备份到/root下,要求每天备...

    信安本原
  • Linux systemd 定时器 timer

    用来取代 crontab systemd 系列文章请查看:https://www.khs1994.com/tags/systemd/ 要使用定时器必须编写两个...

    康怀帅
  • Linux定时器实现

    通过排序链表来保存定时器,由于链表是排序好的,所以获取最小(最早到期)的定时器的时间复杂度为 O(1)。但插入需要遍历整个链表,所以时间复杂度为 O(n)。如下...

    用户7686797
  • linux定时器时间轮算法

    Linux定时器分为低精度定时器和高精度定时器两种类型,内核对其均有实现。本文讨论的是我们在应用程序开发中比较常见的低精度定时器。作为常用的基础组件,定时器常用...

    changan
  • Linux内核定时器timer_list

    Linux内核版本:linux-3.0.35 开发板:i.MX6S MY-IMX6-EK200 拟定任务:LED闪烁 声明:嵌入式新手,如有错误还...

    Jack_Cui
  • Linux crontab定时执行任务命令格式与详细例子

    基本格式 :  *  *  *  *  *  command  分 时 日 月 周 命令  第1列表示分钟1~59 每分钟用*或者 */1表示  第2列表示小时...

    流柯
  • 定时器篇:定时任务入门小案例

  • JAVA定时器简单实例

    import java.util.Timer; import java.util.TimerTask;

    用户2192970
  • Laravel框架实现定时Task Scheduling例子

    在网站开发中,需要经常开启一些定时任务,例如定时清理脏数据等。本文主要介绍使用laravel自带的Task Scheduling配合cron实现定时任务。

    砸漏
  • C-Linux_定时器示例使用

    张诺谦
  • Linux时间子系统之时间的表示示例详解

    在Linux内核中,为了兼容原有的代码,或者符合某种规范,并且还要满足当前精度日益提高的要求,实现了多种与时间相关但用于不同目的的数据结构:

    砸漏
  • 简单谈谈Linux内核定时器

    软件意义上的定时器最终依赖硬件定时器来实现, 内核在时钟中断发生后检测各定时器是否到期 , 到期后的定时器处理函数将作为软中断在底半部执行 。实质上,时钟中断处...

    砸漏
  • Linux内核时钟系统和定时器实现

    在上面工作方式下,Linux 2.6.16 之前,内核软件定时器采用timer wheel多级时间轮的实现机制,维护操作系统的所有定时事件。timer whee...

    用户8639654
  • 在 Linux 上使用 systemd 设置定时器

    定时器增加了另一种启动服务的方式,基于……时间。尽管与定时任务很相似,但 systemd 定时器稍微地灵活一些。让我们看看它是怎么工作的。

    用户8989785
  • 4-MSP430定时器_定时器中断

    一开始没写好就上传了,,,,,,,,这次来个全的 自己学MSP430是为了写一篇关于PID的文章,需要430在proteus上做仿真,一则认为在自动控制算法上P...

    杨奉武
  • 速读原著-TCP/IP(TCP定时器示例)

    为了观察到实际中的坚持定时器,我们启动一个接收进程。它监听来自客户的连接请求,接受该连接请求,然后在从网上读取数据前休眠很长一段时间。

    cwl_java

扫码关注云+社区

领取腾讯云代金券