首页 > 编程知识 正文

linux定时器怎么设置时间,定时器工作原理

时间:2023-05-06 15:02:15 阅读:54481 作者:3588

1. POSIX定义的计时器

因为上次有setitimer计时器的介绍,所以我想我基本上知道Linux上计时器的使用方法。 我个人在使用setitimer计时器时,有非常头疼的问题。 是http://www.Sina.com/http://www.Sina.com /。 http://www.Sina.com/http://www.Sina.com/http://www.Sina.com /即ITIMER_REAL、ITIMER_VIRTUAL和ITIMER_PROF 解决方法是使用POSIX中定义的计时器。

POSIX可以理解为一组新标准,用于定义支持创建相同类型的多个计时器的新计时器函数timer_create。

POSIX上的计时器分为三个阶段,主要是三个函数的使用:

如何创建新计时器并在过期时通知进程setitimer

计时器定时器不能设置多个

计时器严格意义上讲,

2. timer_create () timer_create ) )函数的作用是创建计时器并定义过期时如何通知进程。 如果创建成功,则返回0;如果创建失败,则返回-1。 函数的具体参数如下:

#define _POSIX_C_SOURCE 199309 //源代码为符合POSIX的# includesignal.h # include time.hint timer _ create (时钟id 对or -1 on error这三个参数的理解很重要,http://www.Sina.com/http://www.Sina.com /是用于设置计时器的时间,在setitimer ()中有三种时间

3358 www.Sina.com/http://www.Sina.com /,evp的具体结构体定义很复杂,不作介绍。 但是,从功能上来说,evp决定计时器到期时通知程序的方式。 与settimer函数相比,evp除了以信号通知计时器已过期外,还提供了其他方法。 其中需要熟悉evp的两个成员变量是在evp结构中定义的变量,setitimer表示如何通知程序,如果该变量的值为SIGEV_SIGNAL,则用信号通知当然,也可以使用其他字段,如下图所示。

定时器只能按照时间处理的类别,分别设置三种定时器在以信号通知时表示该信号的名称。 此变量的赋值是可选的,http://www.Sina.com/http://www.Sina.com/http://www.Sina.com /解决了setitimer计时器无法设置多个计时器的问题

第三个参数是timer_t类型的指针timerid,但实际上该参数也是为了设置多个计时器而提供的。 http://www.Sina.com/http://www.Sina.com /从后面启动,在停止或删除某个计时器时启动

到句柄的作用。具体使用看后面实例就很容易明白。

3. 启动或停止定时器timer_settime()

设定好的定时器,需要经过timer_settime()函数进行启动或停止,这个函数有四个参数。

#define _POSIX_C_SOURCE 199309#include <time.h>int timer_settime(time_t timerid, int flags, const struct itimerspec *value, struct itimerspec *old_value);return 0 on success, or -1 on error

第一个参数用来定位具体的定时器,即告诉timer_settime()函数,哪个定时器需要启动或停止,该参数就是上面timer_create()函数的第三个参数。

关于value和old_value,其定义和setitimer()中类似,可以参看前一篇博客。一般不关心定时器之前的状态,old_value设为NULL,value中包含了首次触发定时器的时间以及该定时器是否按特定的时间周期性的执行。

4. 删除定时器timer_delete()

删除定时器就相对容易理解,提供相应的定时器句柄timerid,就可以删除对应的定时器。

#define _POSIX_C_SOURCE 199309#include <time.h>int timer_delete(timer_t timerid);return 0 on success, or -1 on error 5. 简单实例

下面的例子是通过POSIX下的定时器设定实时时间的两个定时器,但是触发的周期不同。信号名使用了SIGUSR1和SIGUSR2,这两个信号都是由头文件signal.h的头文件中提供的,如果还需要更多的定时器,可以参考该头文件中的其他信号名,也可以通过宏将其中的信号名变为自己熟悉的名称。

#define _POSIX_C_SOURCE 199309#include <signal.h>#include <time.h>#include <sys/time.h>#include <string.h>#include <stdlib.h>#include <iostream>#define TIMER_SIG SIGRTMAXusing namespace std;static void sigHandler1(int sig){ cout << "alarm1 has been triggered" << endl;}static void sigHandler2(int sig){ cout << "alarm2 has been triggered" << endl;}int main(){ //struct sigaction sa; struct sigevent sev1; timer_t t1; // 第一个定时器的标识 struct itimerspec itv1; // 声明一个定时器时间设置 // 设置定时器参数.表示定时器从0时刻启动,每2s重复一次 itv1.it_value.tv_sec = 0; itv1.it_value.tv_nsec = 1; itv1.it_interval.tv_sec = 3; itv1.it_interval.tv_nsec = 0; struct sigevent sev2; timer_t t2; // 第二个定时器的标识 struct itimerspec itv2; // 声明一个定时器时间设置 // 设置定时器参数.表示定时器从0时刻启动,每1s重复一次 itv2.it_value.tv_sec = 0; itv2.it_value.tv_nsec = 1; itv2.it_interval.tv_sec = 1; itv2.it_interval.tv_nsec = 0; signal(SIGUSR1, sigHandler1); signal(SIGUSR2, sigHandler2); sev1.sigev_notify = SIGEV_SIGNAL;// 表示通过信号来通知进程计时器到时 sev1.sigev_signo = SIGUSR1; // 设定信号的名称 sev2.sigev_notify = SIGEV_SIGNAL;// 表示通过信号来通知进程计时器到时 sev2.sigev_signo = SIGUSR2; // 设定信号的名称 timer_create(CLOCK_REALTIME, &sev1, &t1); timer_settime(t1, 0, &itv1, NULL); timer_create(CLOCK_REALTIME, &sev2, &t2); timer_settime(t2, 0, &itv2, NULL); for(;;){} return 0;}

程序执行的结果如下,定时器1每3秒触发一次,定时器2每1秒触发一次。

alarm1 has been triggeredalarm2 has been triggeredalarm2 has been triggeredalarm2 has been triggeredalarm1 has been triggeredalarm2 has been triggeredalarm2 has been triggeredalarm2 has been triggeredalarm1 has been triggeredalarm2 has been triggeredalarm2 has been triggeredalarm2 has been triggeredalarm1 has been triggeredalarm2 has been triggeredalarm2 has been triggeredalarm2 has been triggeredalarm1 has been triggeredalarm1 has been triggeredalarm2 has been triggered

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。