在服务端程序设计中,与时间有关的常见任务有:
Linux 的计时函数,用于获得当前时间:
定时函数,用于让程序等待一段时间或安排计划任务:
一般情况下
获取当前时间常用
gettimerofday,因为它的精度是1us,并且在x86平台上它是用户态实现的,没有系统调用和上下文切换的开销。
定时函数中:
下面是用timer_create实现的一个定时器:
#include <stdio.h> #include <time.h> #include <stdlib.h> #include <signal.h> #include <string.h> #include <unistd.h> void sig_handler(int signo) { switch(signo) { case SIGUSR1: printf("receive sigusr1! \n"); break; case SIGALRM: printf("receive sigarlm!\n"); break; } } int main() { /** struct sigaction { void (*sa_handler)(int);信号响应函数地址 void (*sa_sigaction)(int, siginfo_t *, void *); 但sa_flags为SA——SIGINFO时才使用 sigset_t sa_mask; 说明一个信号集在调用捕捉函数之前,会加入进程的屏蔽中,当捕捉函数返回时,还原 int sa_flags; void (*sa_restorer)(void);未用 }; */ timer_t timer1, timer2; struct sigevent evp1, evp2; struct sigaction act; //for timer1 memset(&act, 0, sizeof(act)); act.sa_handler = sig_handler; act.sa_flags = 0; sigemptyset(&act.sa_mask); if (sigaction(SIGUSR1, &act, NULL) == -1) { perror("fail to sigaction"); exit(-1); } //for timer2 memset(&act, 0, sizeof(act)); act.sa_handler = sig_handler; act.sa_flags = 0; sigemptyset(&act.sa_mask); if (sigaction(SIGALRM, &act, NULL) == -1) { perror("fail to sigaction"); exit(-1); } //for timer1 memset(&evp1, 0, sizeof(struct sigevent)); evp1.sigev_signo = SIGUSR1; evp1.sigev_notify = SIGEV_SIGNAL; if (timer_create(CLOCK_REALTIME, &evp1, &timer1) == -1) { perror("fail to timer_create"); exit(-1); } struct itimerspec it; it.it_interval.tv_sec = 2; it.it_interval.tv_nsec = 0; it.it_value.tv_sec = 1; it.it_value.tv_nsec = 0; if (timer_settime(timer1, 0, &it, 0) == -1) { perror("fail to timer_settime"); exit(-1); } //for timer2 memset(&evp2, 0, sizeof(struct sigevent)); evp2.sigev_signo = SIGALRM; evp2.sigev_notify = SIGEV_SIGNAL; if (timer_create(CLOCK_REALTIME, &evp2, &timer2) == -1) { perror("fail to timer_create"); exit(-1); } it.it_interval.tv_sec = 4; it.it_interval.tv_nsec = 0; it.it_value.tv_sec = 2; it.it_value.tv_nsec = 0; if (timer_settime(timer2, 0, &it, 0) == -1) { perror("fail to timer_settime"); exit(-1); } for(;;); return 0; }
以及一个用setitimer实现的定时器
setitimer中的第一个参数有三类:
这里说得很清楚。
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_VIRTUAL, this timer is usually used to profile the time spent by the application in user and kernel space. SIGPROF is delivered upon expiration.
#include <signal.h> #include <stdio.h> #include <string.h> #include <sys/time.h> void timer_handler (int signum) { switch(signum) { case SIGALRM: printf("sigarlm !\n"); break; case SIGVTALRM: printf("sigvtalrm !\n"); break; } } int main () { struct sigaction sa; struct itimerval timer; memset (&sa, 0, sizeof (sa)); sa.sa_handler = &timer_handler; sigaction (SIGVTALRM, &sa, NULL); sa.sa_handler = &timer_handler; sigaction(SIGALRM, &sa, NULL); timer.it_value.tv_sec = 0; timer.it_value.tv_usec = 250000; timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 250000; setitimer (ITIMER_REAL, &timer, NULL); timer.it_value.tv_sec = 1; timer.it_value.tv_usec = 0; timer.it_interval.tv_sec = 1; timer.it_interval.tv_usec = 0; setitimer (ITIMER_VIRTUAL, &timer, NULL); while (1); }
参考:http://www.cnblogs.com/Solstice/archive/2011/02/06/1949555.html