linux时钟中断分析
前置知识
linux内部有三个内置定时器:
-
ITIMER_REAL:实时定时器,不管进程在何种模式下运行(甚至在进程被挂起时),它总在计数。定时到达,向进程发送SIGALRM信号。
-
ITIMER_VIRTUAL:这个不是实时定时器,当进程在用户模式(即程序执行时)计算进程执行的时间。定时到达后向该进程发送SIGVTALRM信号。
-
ITIMER_PROF:进程在用户模式(即程序执行时)和核心模式(即进程调度用时)均计数。定时到达产生SIGPROF信号。ITIMER_PROF记录的时间比ITIMER_VIRTUAL多了进程调度所花的时间。
根据定时器编写程序
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>
#include "time_1.h"
static void sig_handler(int signo);
int lastsec, countsec;
int main(void)
{
struct itimerval v;
long nowsec, nowusec;
// C 库函数 void(*signal(int sig, void (*func)(int)))(int)
// 设置一个函数来处理信号,即带有 sig 参数的信号处理程序。
// SIGUSR1 用户自定义信号 默认处理:进程终止
if (signal(SIGUSR1, sig_handler) == SIG_ERR)
{
printf("create SIGUSR.fail\n");
exit(0);
}
if (signal(SIGALRM, sig_handler) == SIG_ERR)
{
printf("create sigalrm fail\n");
exit(0);
}
printf("I AN RUNNING PID IS %d\n", getpid());
v.it_interval.tv_sec = 9;
v.it_interval.tv_usec = 999999;
v.it_value.tv_sec = 9;
v.it_value.tv_usec = 999999;
setitimer(ITIMER_REAL, &v, NULL);
// 设置定时器
lastsec = v.it_value.tv_sec;
countsec = 0;
while (1)
{
getitimer(ITIMER_REAL, &v);
nowsec = v.it_value.tv_sec;
nowusec = v.it_value.tv_usec;
if (nowsec == lastsec - 1)
{
raise(SIGUSR1);
lastsec = nowsec;
countsec++;
}
}
}
// 定时执行的函数
static void sig_handler(int signo)
{
switch (signo)
{
case SIGUSR1:
printf("one sec passed\n");
break;
case SIGALRM:
{
printf("TIMER HAS BEEN ZERO ELAPSED %D SEC\n", countsec);
lastsec = countsec;
countsec = 0;
break;
}
default:
break;
}
}
运行结果
定时器运行中
kill进程后:
总结
定时器能够定时的执行一个任务,通过实现sighandler函数。并且在定时器运行过程中还可以受命令控制。
结语
本次的文章到这里就结束啦!♥♥♥读者大大们认为写的不错的话点个赞再走哦 ♥♥♥
每天一个知识点,每天都在进步!♥♥