首页 > 代码库 > linux中使用定时器

linux中使用定时器

1.使用14号信号SIGALRM,调用alarm函数

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>

void handle(int signum)
{
 printf("hello\n");
}

int main(int argc, const char *argv[])
{
    signal(SIGALRM, handle);
    while(1)
    {
        alarm(3);
        sleep(3);
    }
    return 0;
}

//每隔3秒向自身发送一个SIGALRM信号,signal收到 SIGALRM信号后调用handle进行处理

--》alarm只能精确到秒


2.setitimer  -->也是通过向自身发送信号进行处理的,不过可以精确到毫妙级别

int setitimer(int which, const struct itimerval *new_value,
                     struct itimerval *old_value);

ITIMER_REAL    decrements in real time, and delivers SIGALRM upon expiration.

ITIMER_VIRTUAL decrements  only  when  the  process  is executing, and delivers
                      SIGVTALRM upon expiration.

ITIMER_PROF    decrements both when the process executes and when the system is
                      executing  on  behalf  of the process.  Coupled with ITIMER_VIR-
                      TUAL, this timer is usually used to profile the  time  spent  by
                      the  application in user and kernel space.  SIGPROF is delivered
                      upon expiration.

 struct itimerval {
               struct timeval it_interval; /* next value */
               struct timeval it_value;    /* current value */
           };

 struct timeval {
               long tv_sec;                /* seconds */
               long tv_usec;               /* microseconds */
           };

--》3种模式产生3中不同的信号,使用方法类似

在该例子中,每隔一秒发出一个SIGALRM,每隔0.5秒发出一个SIGVTALRM信号:

#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;

}

fflush(stdout);

return;

}

int main()

{

struct itimerval value, ovalue, value2; //(1)

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); //(2)

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(;;)

;

}


3.timerfd_create   timerfd_settime   -->通过时间设置fd可读,然后通过select轮询,调用处理函数

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/timerfd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>

#define ERR_EXIT(m)     do {         perror(m);        exit(EXIT_FAILURE);    }while(0)

int main(int argc, const char *argv[])
{
    struct itimerspec time;
    time.it_value.tv_sec = 5;
    time.it_interval.tv_sec = 2;

    int timerfd = timerfd_create(CLOCK_REALTIME, 0);
    if(timerfd == -1)
        ERR_EXIT("timerfd_create");

    if(timerfd_settime(timerfd, 0, &time, NULL) == -1)
        ERR_EXIT("timerfd_settime");

    fd_set read1, ready;
    FD_ZERO(&read1);
    FD_SET(timerfd, &read1);
    char buf[1024];
    struct timeval time_select;
    while(1)
    {
        time_select.tv_sec = 3;//必须定义在while内部
        time_select.tv_usec = 11;
        ready = read1;
        int nready = select(timerfd + 1, &ready, NULL, NULL, &time_select);//设置为一直阻塞
        if(nready == -1)
            ERR_EXIT("select");
        else if(nready == 0)
            printf("timeout");
        else
        {
            if(-1 == read(timerfd, buf, sizeof buf))
            {
                printf("%s\n", strerror(errno));//打印错误信息
                ERR_EXIT("read");
            }
            printf("come\n");
        }
    }
    return 0;
}

4.直接使用select   -->精确到毫秒级别

int msSleep(long ms) {

    struct timeval tv;

    tv.tv_sec = 0;

    tv.tv_usec = ms;

     return select(0, NULL, NULL, NULL, &tv);
}

其他资料:

http://www.cppblog.com/CppExplore/archive/2008/04/02/46111.html 












linux中使用定时器