Linux定时器
来源:互联网 发布:利用淘宝双十一赚钱 编辑:程序博客网 时间:2024/05/25 18:10
Linux提供了2个函数来实现定时器功能:alarm函数和setitimer函数。
1、alarm函数
如果对定时要求不太精确的话,使用alarm()和signal()就行了。
函数原型:unsigned int alarm(unsigned int seconds)
<pre name="code" class="cpp">
#include <stdio.h>#include <unistd.h>#include <signal.h>void time_handler(int sig){ printf("alarm!\n"); alarm(2); return;}int main(void){ signal(SIGALRM, time_handler); alarm(2); while(true) { sleep(1); }}
注意:alarm只设定一个闹钟,时间到达并执行其注册函数之后,闹钟便失效。如果想循环设置闹钟,需在其注册函数中在调用alarm函数。
2、setitimer函数
函数原型int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));
setitimer()比alarm功能强大,支持3种类型的定时器:
ITIMER_REAL : 以系统真实的时间来计算,它送出SIGALRM信号。
ITIMER_VIRTUAL : -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。
ITIMER_PROF : 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <time.h>#include <sys/time.h>void time_handler(int sig){ switch (sig){ case SIGALRM: printf("Catch a signal -- SIGALRM \n"); break; case SIGVTALRM: printf("Catch a signal -- SIGVTALRM \n"); break; } return;}int main(){ struct itimerval value, ovalue, value2; //(1) signal(SIGALRM, time_handler); signal(SIGVTALRM, time_handler); value.it_value.tv_sec = 1; value.it_value.tv_usec = 0; value.it_interval.tv_sec = 1; value.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &value, &ovalue); //(2) value2.it_value.tv_sec = 2; value2.it_value.tv_usec = 0; value2.it_interval.tv_sec = 2; value2.it_interval.tv_usec = 0; setitimer(ITIMER_VIRTUAL, &value2, &ovalue); while(true) {sleep(1); }}
- struct itimerval {
- struct timeval it_interval; /* next value */
- struct timeval it_value; /* current value */
- };
- struct timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* microseconds */
- };
setitimer函数是注册内核中的定时器,这种定时器不会引起线程的切换,不会引起线程的阻塞。ITIMER_REAL间隔定时器是利用动态定时器实现的,即使进程不在CPU上运行时,内核也必须向进程发送信号。因此,每个进程描述符包含一个real_timer的动态定时器对象。ITIMER_VIRTUAL和ITIMER_PROF间隔定时器不需要动态定时器,因为只有当进程运行时,它们才被更新。
3、多定时器的实现
多定时器,有的通过gettimeofday函数获取时间差,通过计算时间差来实现多定时器。这边我介绍一种简单的多定时器实现方法。
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <time.h>#include <sys/time.h>#define TIMER_1 1#define TIMER_2 2#define TIMER_3 3void time_handler(int sig,siginfo_t *si,void *uc){long long *tid=(long long)si->si_ptr;switch(*tid){case TIMER_1:printf("This is Timer_1!");break;case TIMER_1:printf("This is Timer_2!");break;case TIMER_1:printf("This is Timer_3!");break;}}void timer_init(){struct itimerspec value1,value2,value3;struct sigcation sa;struct sigevent sev;timer_t tidlist[3];tidlist[0]=(timer_t*)TIMER_1;tidlist[1]=(timer_t*)TIMER_2;tidlist[0]=(timer_t*)TIMER_3;sa.sa_flags=SA_SIFINFO;sa.sa_sigaction=timer_handler;sigemptyset(&sa.sa_mask);sigcation(SIGRTMAX,&sa,NULL);sev.sigev_notify=SIGEV_SIGNAL;sev.sigev_signo=SIGRTMAX;value1.it_value.tv_sec=10;value1.it_value.tv_nsec=0;value1.it_interval.tv_sec=10;value1.it_interval.tv_nsec=0;value2.it_value.tv_sec=2;value2.it_value.tv_nsec=0;value2.it_interval.tv_sec=2;value2.it_interval.tv_nsec=0;value3.it_value.tv_sec=5;value3.it_value.tv_nsec=0;value3.it_interval.tv_sec=5;value3.it_interval.tv_nsec=0;sev.sigev.sival_ptr=tidlist[0];timer_create(CLOCK_REALTIME,&sev,&tidlist[0]);sev.sigev.sival_ptr=tidlist[1];timer_create(CLOCK_REALTIME,&sev,&tidlist[1]);sev.sigev.sival_ptr=tidlist[2];timer_create(CLOCK_REALTIME,&sev,&tidlist[2]);timer_settime(tidlist[0],0,&value1,NULL);timer_settime(tidlist[1],0,&value2,NULL);timer_settime(tidlist[2],0,&value3,NULL);}int main(){timer_init();while(true){sleep(20);}}当程序运行时,收到信号,将会开启中断服务。在信号处理程序中,不能判断捕捉信号时进程执行到哪里。因此,定时器回调函数中一般不能调用不可重入函数,如malloc函数,特别是在C++字符串string处理中,有时候会频繁申请和释放空间,此时如果主进程也是在频繁申请和释放空间,则可能会死锁。
- linux定时器
- linux定时器
- Linux 定时器
- linux 定时器
- linux定时器
- Linux 定时器
- Linux定时器
- Linux:定时器
- linux 定时器
- linux 定时器
- linux 定时器
- linux 定时器
- linux定时器
- linux 定时器
- linux定时器
- linux 定时器
- linux定时器
- Linux定时器
- 三、对SERVER内的元素信息进行说明
- 关于验证码识别的两种方案
- 安卓事件处理
- ios微秀音乐控制案例
- 一个有意思的拼接数组
- Linux定时器
- Nginx如何解决事件过期问题
- Unity3d GUI与NGUI
- Informatica&DAC
- Java Notes-8
- Quick 3.3中display.newColorLayer的错误
- 史上最简单Robotium跨进程操作实践——基于ADB框架
- 排序专题学习笔记——插入排序
- 《数据结构》课程设计