标签:例子 定时 10个 时间 启动 执行时间 睡眠 内核 alarm
简单定时器
#include<unistd.h>
unsigned int alarm(unsigned int seconds)
返回上一个alarm等待时间,没有则返回0
只能设置 1 个定时器,设置第 2 个时会替换第一个
设置成功后,上一个alarm会失效
定时事件只执行1次,多次执行需要递归调用
等待事件到达后,会给进程发送 SIGALRM信号
捕获 SIGALRM信号并处理
例子:
int g_nValue=0;
void fun(int sig)
{
printf("sig:%d\n",sig);
printf("g_nValue=%d\n",g_nValue);
}
void testAlarm()
{
printf("pid:%d\n",getpid());
//printf("1\n");
int n=0;
n=alarm(1);
//printf("%d\n",n);
//printf("2\n");
signal(SIGALRM,fun);
//printf("3\n");
while(1)
{
g_nValue++;
}
}
注意:alarm()定时器结束后,才发出SIGALRM信号。如alarm(100),不是启动alarm就发出,而是启动后100秒才发出信号。
一个定时器多次使用:
只需在信号处理函数再一次使用alarm()即可。
void fun(int sig)
{
printf("sig:%d\n",sig);
printf("g_nValue=%d\n",g_nValue);
alarm(1);
}
alarm只能一个定时器,如果要该定时器不同秒数启动。即实现多个定时器的功能。
方式:设置一个标志位,用来标志秒数
void fun(int sig)
{
static flag=0;
flag++
//1秒
alarm(flag);
if(flag%2==0)
{
//2秒
alarm(flag);
}
if(flag%5==0)
{
//5秒
alarm(flag);
}
//...............
printf("sig:%d\n",sig);
}
sleep与定时器的区别:
sleep是使程序进入休眠状态,即sleep后面的代码不会继续运行,直到休眠结束。
alarm定时器开始后,代码也会继续往下运行。
sleep对定时器的影响:
void fun(int sig)
{
//printf("sig:%d\n",sig);
printf("!");
alarm(1);
}
void testAlarm()
{
printf("pid:%d\n",getpid());
int n=0;
n=alarm(1);
signal(SIGALRM,fun);
while(1)
{
sleep(10);
printf("@");
}
}
结果输出:
pid:9282
!@!@!@.......
问题:定时器是1秒,sleep是10秒。不应该是10个!才是一个@吗?
此时就涉及到进程调度问题。程序原是运行态,sleep使程序进入了睡眠态。但是睡眠态无法直接回到运行态,只能到就绪态,等待cpu执行。
精准定时器
<sys/select.h>
<sys/time.h>
int getitimer(int which, struct itimerval *value)
int setitimer(int which, struct itimerval *new, struct itimeval *old)
which取值:提供三种定时器,可以同时存在
ITIMER_REAL (0)
发送信号:SIGALRM
定义真实CPU时间(所有进程的CPU时间都累计),同 alarm
ITIMER_VIRTUAL (1)
发送信号:SIGVTALRM
定义进程在用户态下的实际执行时间(只累计自己用户态的CPU时间)
ITIMER_PROF (2)
发送信号: SIGPROF
定义进程在用户态和内核态的实际执行时间(只累计自己的CPU时间)
注意:因为alarm 和ITIMER_REAL都是发出同一个信号SIGALRM,因此larm 和 setitimer(ITIMER_REAL, ...) 不能同时使用
struct itimerval
{
struct timeval it_interval; //下次定时取值;后续定时间隔时间
struct timeval it_value; //本次定时设置值;定时器第一次到达时间
}
struct timeval {
time_t tv_sec; /* 秒 */
suseconds_t tv_usec; /* 微妙 */
};
定时器开始后
1. 先把 it_value 减少到0
2. 把 it_interval 复制给 it_value; (it_inverval=0则停止定时器)
3. 继续下一次定时循环
例子:
void func(int sig)
{
//printf("sig:%d\n",sig);
switch(sig)
{
case SIGALRM:
{
printf("SIGALRM....\n");
break;
}
case SIGVTALRM:
{
printf("SIGVTALRM....\n");
break;
}
case SIGPROF:
{
printf("SIGPROF....\n");
break;
}
}
}
void testMircoTimer()
{
printf("pid:%d\n",getpid());
struct itimerval new;
//本次定时器间隔秒数
new.it_interval.tv_sec=0;
new.it_interval.tv_usec=500*1000; //0.5
//下次定时器间隔秒数
new.it_value.tv_sec=1;
new.it_value.tv_usec=500*1000; //0.5
//创建三种定时器
setitimer(ITIMER_REAL,&new,NULL);
setitimer(ITIMER_VIRTUAL,&new,NULL);
setitimer(ITIMER_PROF,&new,NULL);
signal(SIGALRM,func);
signal(SIGVTALRM,func);
signal(SIGPROF,func);
while(1)
{
}
}
标签:例子 定时 10个 时间 启动 执行时间 睡眠 内核 alarm
原文地址:https://www.cnblogs.com/gd-luojialin/p/9216005.html