Linux编程——定时器

定时器

1.创建定时器

关于使用POSIX定时器的创建,使用timer_create函数创建,定时以下提供了简单的示例。

```c

#include <time.h>

// 定义定时器结构体

typedef struct {

    timer_t hTimerHandle;

    // 其他定时器相关的成员变量

} TimerData;

// 创建定时器函数

void createTimer() {

    TimerData timerData;

    struct sigevent se;

    // 设置定时器事件

    se.sigev_notify = SIGEV_SIGNAL;  // 定时器到期时发送信号

    se.sigev_signo = SIGALRM;       // 使用SIGALRM信号

    se.sigev_value.sival_ptr = &(timerData.hTimerHandle);  // 传递定时器句柄

    // 创建定时器

    timer_create(CLOCK_REALTIME, &se, &(timerData.hTimerHandle));

    // 其他处理定时器的操作

}

```

在上述代码中,timer_create函数用于创建一个定时器。它接受三个参数:

1. clockid_t clockid:指定定时器时钟类型,这里使用CLOCK_REALTIME表示使用实时时钟。

2. struct sigevent *sevp:指向sigevent结构体的指针,该结构体定义了定时器到期时的处理方式。

3. timer_t *timerid:指向timer_t类型的指针,用于接收创建的定时器句柄。

在代码中,首先定义了一个TimerData结构体,用于存储定时器句柄和其他相关的定时器数据。

然后,创建了一个sigevent结构体se,并设置了定时器事件的处理方式。最后,通过调用timer_create函数,将定时器句柄存储在timerData.hTimerHandle中,注意这里创建时钟是CLOCK_REALTIME,实时时钟,可以保证一定的实时性能。

在定时器创建时,还支持一些其他的事件类型,如SIGEV_THREAD等,时间到创建一个新的线程来执行特定的函数。

```c

typedef struct sigevent {

    int sigev_notify;              // 通知方式

    int sigev_signo;               // 信号编号

    union sigval sigev_value;      // 传递的值

    void (*sigev_notify_function)(union sigval);  // 线程处理函数

    pthread_attr_t *sigev_notify_attributes;      // 线程属性

} sigevent_t;

```

```c

#include <time.h>

#include <pthread.h>

// 定时器线程处理函数

void timerThreadHandler(union sigval value) {

    // 处理定时器到期事件

}

// 创建定时器函数

void createTimer() {

    struct sigevent se;

    timer_t timerid;

    // 设置定时器事件

    se.sigev_notify = SIGEV_THREAD;  // 使用线程处理方式

    se.sigev_notify_function = timerThreadHandler;  // 设置线程处理函数

    se.sigev_notify_attributes = NULL;

    // 创建定时器

    timer_create(CLOCK_REALTIME, &se, &timerid);

    // 其他处理定时器的操作

}

```

2.设置定时器的时间,启动定时器

`struct itimerspec`是一个用于设置定时器的结构体,在Linux中定义在<sys/time.h>头文件中。它包含两个成员变量:it_interval和it_value。

```c

struct itimerspec {

    struct timespec it_interval;  // 定时器的间隔时间

    struct timespec it_value;     // 定时器的初始值

};

```

其中,每个成员变量的含义如下:

1. it_interval:表示定时器的间隔时间,即定时器周期性触发的时间间隔。它是一个struct timespec结构体类型的变量,包含了秒(tv_sec)和纳秒(tv_nsec)两个字段。如果希望定时器只触发一次,可以将it_interval设置为0。

2. it_value:表示定时器的初始值,即定时器首次触发的时间。同样,它也是一个struct timespec结构体类型的变量。

通过设置it_interval和it_value的值,可以控制定时器的触发时间和触发频率。

以下是使用struct itimerspec结构体来设置定时器的间隔时间和初始值的示例:

```c

#include <sys/time.h>

void setTimer() {

    timer_t timerid;

    struct itimerspec its;

    // 设置定时器间隔时间为2秒,初始值为3秒

    its.it_interval.tv_sec = 2;

    its.it_interval.tv_nsec = 0;

    its.it_value.tv_sec = 3;

    its.it_value.tv_nsec = 0;

    // 设置定时器

    timer_settime(timerid, 0, &its, NULL);

    // 其他处理定时器的操作

}

```

首先定义了一个itimerspec结构体变量its,并设置了定时器的间隔时间和初始值。然后,通过调用timer_settime函数来设置定时器。最后,可以进行其他处理定时器的操作。

需要注意的是,it_interval.tv_nsec和it_value.tv_nsec的时间单位是纳秒。在设置定时器时,可以根据需要将其设为不同的值,以实现所需的定时触发行为。

3.停止定时器

停止定时器相对比较简单,将时间相关参数设置为0即可。

```c

static struct itimerspec its = {{0, 0}, {0, 0}};  

timer_settime(timerData.hTimerHandle, 0, &its, NULL);

```

4.删除定时器

要删除定时器,需要等定时器停止运行之后才能删除,所以第一步应停止定时器。

```c

timer_delete(timerData.hTimerHandle);

//对于存放定时器相关数据的结构体可以清空

memset(&timeData, (uint8_t)0x00, sizeof(TimerData));

```

在Android UWB HAL实现中,对定时器进行了一定的封装,如下:

```c

/*

 **Timer Handle structure containing details of a timer.

 */

typedef struct phOsalUwb_TimerHandle {

    timer_t hTimerHandle; /* Handle of the timer */

    /* Timer callback function to be invoked */

    pphOsalUwb_TimerCallbck_t Application_callback;

    void* pContext; /* Parameter to be passed to the callback function */

    phOsalUwb_TimerStates_t eState; /* Timer states */

    /* Osal Timer message posted on User Thread */

    phLibUwb_Message_t tOsalMessage;


    //...

} phOsalUwb_TimerHandle_t, *pphOsalUwb_TimerHandle_t;

```

在timer_t句柄的基础之上增加了相关的回调函数、消息、上下文参数等等,基于定时器实现相关的访问需求。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 介绍 最强大的定时器接口来自POSIX时钟系列,其创建、初始化以及删除一个定时器的行动被分为三个不同的函数:tim...
    ColdsteelRail阅读 3,573评论 0 1
  • 在上一节已经了解到Linux上使用各种定时器的优缺点,接下来主要介绍Posix定时器。传送门:关于Linux应用层...
    JalynFang阅读 10,062评论 0 4
  • 1.创建定时器 QNX定时器首先需要创建一个定时器对象,设置通知类型,一般包括信号、脉冲或线程创建,并创建通知结构...
    jackniu_ae28阅读 1,267评论 0 0
  • timerfd为Linux为用户程序提供的定时器接口,该接口基于文件描述符,通过文件描述符的可读事件进行超时通知,...
    agin719阅读 13,001评论 0 2
  • 开发平台 芯灵思Sinlinx A64内存: 1GB 存储: 4GB开发板详细参数 https://m.tb.cn...
    sinlinx123阅读 307评论 0 0

友情链接更多精彩内容