首页 > 代码库 > Linux下的定时器

Linux下的定时器

1.alarm()运行后,进程将继续运行。在后期(alarm以后)的运行过程中将会在seconds秒后收到信号SIGALRM并运行其处理函数。

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void sigalrm_fn(int sig)
{
    printf("alarm!\n");
    alarm(2);
    return;
}
int main(void)
{
    signal(SIGALRM, sigalrm_fn);
    alarm(1);
    while(1) pause();
}

2.alarm定时器,可是仅仅能精确到秒,然而我们假设须要用到更精准的定时器能够用setitimer
 int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));
 setitimer()比alarm功能强大,支持3种类型的定时器:
    ITIMER_REAL :     以系统真实的时间来计算。它送出SIGALRM信号。
    ITIMER_VIRTUAL : -以该进程在用户态下花费的时间来计算。它送出SIGVTALRM信号。
    ITIMER_PROF :     以该进程在用户态下和内核态下所费的时间来计算。它送出SIGPROF信号。
    setitimer()第一个參数which指定定时器类型(上面三种之中的一个)。第二个參数是结构itimerval的一个实例;第三个參数可不做处理。


    setitimer()调用成功返回0。否则返回-1。

    以下是关于setitimer调用的一个简单示范,在该样例中,每隔一秒发出一个SIGALRM。每隔0.5秒发出一个SIGVTALRM信号:[code=C/C++]

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
int sec;
void sigroutine(int signo){
    switch (signo){
        case SIGALRM:
            printf("Catch a signal -- SIGALRM \n");
            signal(SIGALRM, sigroutine);
            break;
        case SIGVTALRM:
            printf("Catch a signal -- SIGVTALRM \n");
            signal(SIGVTALRM, sigroutine);
            break;
    }
    return;
}
int main()
{
    struct itimerval value, ovalue, value2;          
    sec = 5;
    printf("process id is %d\n", getpid());
    signal(SIGALRM, sigroutine);
    signal(SIGVTALRM, sigroutine);
    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); 
    value2.it_value.tv_sec = 0;
    value2.it_value.tv_usec = 500000;
    value2.it_interval.tv_sec = 0;
    value2.it_interval.tv_usec = 500000;
    setitimer(ITIMER_VIRTUAL, &value2, &ovalue);
    for(;;)
        ;
}
setitimer不会引起线程的堵塞、也不会引起线程的切换动作,就是简单的启动一个定时器,開始定时。并且这样的定时应该是基于内核的。(windwos的settimer是基于一种消息的模型)。setitimer尽管有三种类型ITIMER_REAL,ITIMER_VIRTUAL ITIMER_PROF,可是在同一时间同一进程。一种类型的仅仅能有1个setitimer。


Linux下的定时器