学习日志(十一)
Linux定时器实战
定时器原理:
使用setitimer()函数产生信号(类似中断那种),系统随之使用signal信号处理函数来处理产生的定时信号。从而实现定时器。
setitimer()函数原型:
要包含头文件:#include <sys/time.h>
int setitimer (__itimer_which_t __which,
const struct itimerval *__restrict __new,
struct itimerval *__restrict __old)
setitimer()函数参数说明:
setitimer()将value指向的结构体设为计时器的当前值(也就是第二个参数初始化),假设ovalue不是NULL(第三个参数),将返回计时器原有值。ovalue一般设置为NULL;
第一个参数which:
ITIMER_REAL //数值为0,计时器的值实时递减,发送的信号是SIGALRM。
ITIMER_VIRTUAL //数值为1,进程执行时递减计时器的值,发送的信号是SIGVTALRM。
ITIMER_PROF //数值为2,进程和系统执行时都递减计时器的值,发送的信号是SIGPROF。
第二个参数 看下结构体struct itimerval :
struct itimerval
{
/* Value to put into `it_value' when the timer expires. */
struct timeval it_interval;
/* Time to the next timer expiration. */
struct timeval it_value;
};
struct timeval
{
__time_t tv_sec; /* Seconds. */
__suseconds_t tv_usec; /* Microseconds. */
};
it_interval:计时器的初始值,一般基于这个初始值来加或者来减,看控制函数的参数配置。
it_value:程序跑到这之后,多久启动定时器。
第三个参数:
一般设为NULL,一般不用第三个参数,作用类似于51定时器的8位自动重载功能。
signal信号处理函数:
函数原型:
signal(int signo, void(*func)(int))
第一个参数signo:需要加载处理的信号的编号,例如SIGKILL,SIGALRM;
第二个参数:是一个函数指针,指向信号处理函数。
其中:信号处理函数传递的int类型的参数就是:信号的编号,signo。
很明显,这边捕获对应的信号进行逻辑相关处理为 :
signal(SIGALRM,signal_handler);
注意:包含头文件:#include <signal.h>
最后:
返回说明:
成功运行时,返回0。失败返回-1。errno被设为下面的某个值
EFAULT:value或ovalue是不有效的指针
EINVAL:其值不是ITIMER_REAL。ITIMER_VIRTUAL 或 ITIMER_PROF之中的一个
代码功能:
该代码实现的功能是:1s后开启定时器,然后每隔1s向终端打印hello。
代码:
1 #include "stdio.h"
2 #include "sys/time.h"
3 #include "stdlib.h"
4 #include "signal.h"
5
6
7 void signal_handler(int signo)
8 {
9 static int cnt = 0;
10 cnt++;
11 if(cnt==2000){
12 cnt =0 ;
13 printf("Hello\n");
14 }
15
16 }
17
18 int main()
19 {
20 struct itimerval tim;
21 //it_interval:计时器的初始值,一般基于这个初始值来加或者来减,看控制函数的参数配置。
22 tim.it_interval.tv_sec = 0;
23 tim.it_interval.tv_usec = 500; //定时500微秒
24
25 //it_value:程序跑到这之后,多久启动定时器。
26 tim.it_value.tv_sec = 1;
27 tim.it_value.tv_usec = 0;//1秒后启动定时器
28
29 if(setitimer(ITIMER_REAL,&tim,NULL)==-1){ //设置定时器为递减模式
30 perror("error");
31 exit(-1);
32 }
33
34 signal(SIGALRM,signal_handler);
35 while(1);//防止程序退出;
36
37 return 0;
38 }
现象:
这种方法需要注意的是,一个进程只能创建一个定时器
这种方法需要注意的是,一个进程只能创建一个定时器
这种方法需要注意的是,一个进程只能创建一个定时器