转载地址:http://blog.csdn.net/joker0910/article/details/6795444
比较常用的时间控制函数就是sleep();让我们当前的进程休眠指定的秒数。
系统中的每个进程都有一个私有的闹钟。这个闹钟很像一个计时器,可以设置在一定秒数后的闹钟。 时间一到,时钟就发送一个信号SIGALRM到进程。除非为SIGALRM设置了处理函数,否则信号将杀死这个进程。sleep函数由3个步骤组成:
1.为SIGALRM设置一个处理函数;
2.调用alarm(num_seconds);
3.调用pause。
系统调用pause挂起进程直到信号到达。任何信号都可以唤醒进程,而非仅仅等待SIGALRM。
- #include<stdio.h>
- #include<signal.h>
- int main()
- {
- void wakeup(int);
- printf("about to sleep for 4 second\n");
- signal(SIGALRM, wakeup); // SIGALRM handler
- alarm(4); //set clock unsigned old = alarm(unsigned seconds); old---> the rest seconds if there is a signal.
- pause(); // freeze here
- printf("Morning so soon ?\n");
- }
- void wakeup(int signum)
- {
- #ifndef SHHHH
- printf("Alarm received from kernel\n");
- #endif
- }
进程的三种计时器: 真实、进程和实用
1.ITIMER_REAL : 这个计时器计量真实的时间,无论进程在用户态还是核心态用了多少处理器时间它都记录。当这个计时器用尽,发送SIGALRM消息。
2.ITMER_VIRTUAL: 只有进程在用户态运行时才计时。当虚拟计时器用尽时,发送SIGVTALRM消息。这个时间30s比真实时间30s长。
3.ITIMER_PROF: 这个计时器在进程运行于用户态或由该进程调用而陷入核心态时计时。当这个计时器用尽,发送SIGPROF信号。
在程序中使用间隔计时器要稍微复杂一点,要选择计时器的类型,然后需要选择初始间隔和重复间隔,还要设置在struct itimerval中的值,然后将这个结构体通过调用setitimer传给计时器。为了读取计时器设置,使用getitimer。
- #include<stdio.h>
- #include<sys/time.h>
- #include<signal.h>
- int set_ticker(int n_msecs);
- int main()
- {
- void countdown(int );
- signal(SIGALRM, countdown);
- if(set_ticker(500) == -1)
- perror("set_ticker");
- else
- while(1)
- {
- pause();
- }
- return 0;
- }
- void countdown(int signum)
- {
- static int num = 10;
- printf("%d ..", num--);
- fflush(stdout);
- if(num < 0)
- {
- printf("DONE! \n");
- exit(0);
- }
- }
- int set_ticker(int n_msecs)
- {
- struct itimerval new_timeset;
- long n_sec, n_usecs;
- n_sec = n_msecs / 1000;
- n_usecs = (n_msecs % 1000) * 1000L;
- new_timeset.it_interval.tv_sec = n_sec; // set reload 设置初始间隔
- new_timeset.it_interval.tv_usec = n_usecs; //new ticker value
- new_timeset.it_value.tv_sec = n_sec; //store this 设置重复间隔
- new_timeset.it_value.tv_usec = n_usecs; //and this
- return setitimer(ITIMER_REAL, &new_timeset, NULL);
- //#include<sys/time.h> getitimer(int which, struct itimerval *val)
- //setitimer(int which, const struct itimerval* newval, struct itimerval *oldval);
- //which 指定哪种计时器 ITMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF.
- }
使用signal函数设置countdown来处理SIGALRM信号。然后通过set_ticker来设置微秒数。 set_ticker通过装载初始间隔和重复间隔设置间隔计时器。每个间隔是由两个值组成:秒数和微秒数,如同实数的整数部分和小数部分。计时器开始计时时,控制返回到main。
进入死循环后,调用pause。大约每500us,控制跳转到countdown函数。当num到0时,调用exit结束。
struct itimeal的结构如下:
- struct itimerval
- {
- struct timeval it_value; //初始时间间隔,第一次发信号使用的时间,之后都不用了。
- struct timeval it_interval; //重复时间间隔,第一次发信号之后使用的时间。
- };
- struct timeval
- {
- time_t tv_sec; //second
- suseconds_t tv_usec; //microseconds
- };