Linux 计时器 函数
来源:互联网 发布:自制印章软件 编辑:程序博客网 时间:2024/06/14 13:01
转载地址:http://blog.csdn.net/whz_zb/article/details/6938442
程序注册三个定时器,分别对实际时间、进程使用CPU时间、用户使用CPU时间进行即时,计时时间为10秒。同时设定一个用户信号,当该信号在用户指定的空计次循环后到来。在用户信号到来后,打印各个计时器走过的时间值,并计算出内核所用的时间。到实际时间计时器到达10秒后产生定时器信号时,程序打印各计时器走过的时间,并退出程序。
因为需要获得定时器的时间,因此,我们需要使用setitimer和getitimer计时器。使用这两个计时器要频繁的对itimerval和timeval这两个结构体进行操作。首先,应该对这两个结构体在本实例中常用到的操作进行封装。封装的函数包括,timeval的比较,计算两个timeval的时间差,计算itimerval走过的时间(因为itimerval记录的是定时器剩余时间)。为了显示的需要,我们需要封装一个对timeval打印的函数。
之后,我们需要设计信号和信号处理函数,这里我们一共需要两个信号:SIGALRM和SIGUSR1。因为信号处理函数有一个int型参数,该参数可以用来区分信号。考虑到,两个信号到来以后都需要进行时间计算。因此可以考虑将两个信号写成一个函数,通过参数识别,在不同的位置进行不同的处理。
- #include <stdio.h>
- #include <time.h>
- #include <sys/time.h>
- #include <stdlib.h>
- #include <signal.h>
- /* 函数声明 */
- /* 信号处理函数 */
- static void SigHandler(int signo);
- /* 操作辅助函数 */
- void TimerPassed(const struct itimerval *itimer, struct timeval *tv);
- void TimeSubstract(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tvres);
- int TimeCompare(const struct timeval *tv1, const struct timeval *tv2);
- void PrintTimeval(const char *str, const struct timeval *tv);
- /* 主函数,程序入口点 */
- int main()
- {
- /* 变量声明 */
- struct itimerval myitimer;
- long i, count;
- /* 注册信号处理函数 */
- /* 注册用户信号1处理函数 */
- if (signal(SIGUSR1, SigHandler) == SIG_ERR) {
- printf("Unable to create handler for SIGUSR1\n");
- exit(0);
- }
- /* 定时器信号处理函数 */
- /* 这里将同一个函数注册给两个信号,函数内部存在区分信号类型的逻辑 */
- if (signal(SIGALRM, SigHandler) == SIG_ERR){
- printf("Unable to create handler for SIGALRM\n");
- exit(0);
- }
- /* 运行参数输入 */
- printf("Loop times between timer info outputs (300 Recommanded):\n");
- scanf("%ld", &count);
- count *= 1000000;
- /* 初始化定时器参数 */
- myitimer.it_interval.tv_sec = 10;
- myitimer.it_interval.tv_usec = 0;
- myitimer.it_value.tv_sec = 10;
- myitimer.it_value.tv_usec = 0;
- /* 注册定时器 */
- setitimer(ITIMER_REAL, &myitimer, NULL); /* 实时定时器 */
- setitimer(ITIMER_VIRTUAL, &myitimer, NULL); /* 用户定时器 */
- setitimer(ITIMER_PROF, &myitimer, NULL); /* CPU定时器 */
- /* 无限循环,等待信号处理 */
- while (1)
- {
- for (i=0; i < count; i++);
- /* 每进行指定次数的循环后,发送用户信号1给自己 */
- raise(SIGUSR1);
- }
- }
- /* 信号处理函数 */
- static void SigHandler(int signo)
- {
- /* 变量声明 */
- struct itimerval tmp_itimer;
- struct timeval realtv, cputv, usertv, kerneltv;
- /* 获得实时定时器时间 */
- getitimer(ITIMER_REAL, &tmp_itimer);
- TimerPassed(&tmp_itimer, &realtv);
- /* 获得CPU定时器时间 */
- getitimer(ITIMER_PROF, &tmp_itimer);
- TimerPassed(&tmp_itimer, &cputv);
- /* 获得用户定时器时间 */
- getitimer(ITIMER_VIRTUAL,&tmp_itimer);
- TimerPassed(&tmp_itimer, &usertv);
- /* 计算Linux内核使用CPU时间 */
- TimeSubstract(&cputv, &usertv, &kerneltv);
- /* 按照信号进行处理 */
- switch (signo)
- {
- /* 用户信号1 */
- case SIGUSR1:
- /* 输出各种时间值 */
- PrintTimeval("Real Time ", &realtv);
- PrintTimeval("CPU Time ", &cputv);
- PrintTimeval("User Time ", &usertv);
- PrintTimeval("Kernel Time", &kerneltv);
- printf("\n");
- break;
- /* 定时器信号 */
- case SIGALRM:
- /* 输出时间值后退出程序 */
- printf("Time up, the application will escape.\n");
- PrintTimeval("CPU Time ", &cputv);
- PrintTimeval("User Time ", &usertv);
- PrintTimeval("Kernel Time", &kerneltv);
- exit(0);
- break;
- }
- }
- /* 计算时间的流逝 */
- void TimerPassed(const struct itimerval *itimer, struct timeval *tv)
- {
- TimeSubstract(&(itimer->it_interval), &(itimer->it_value), tv);
- }
- /* 计算两个时间的差值 */
- void TimeSubstract(const struct timeval *tv1, const struct timeval *tv2, struct timeval *tvres)
- {
- /* 变量声明 */
- const struct timeval *tmptv1, *tmptv2;
- int cmpres;
- /* 比较tv1和tv2,将较大值赋给tmptv1,较小值赋给tmptv2 */
- cmpres = TimeCompare(tv1, tv2);
- if (cmpres > 0) {
- tmptv1 = tv1;
- tmptv2 = tv2;
- }
- else {
- tmptv1 = tv2;
- tmptv2 = tv1;
- }
- /* 做差时存在借位的情况 */
- if (tmptv1->tv_usec < tmptv2->tv_usec) {
- /* 结果的秒数多减1,借给微秒 */
- tvres->tv_sec = tmptv1->tv_sec - tmptv2->tv_sec - 1;
- /* 微秒做减法时,先加上借来的一秒(1000000微秒) */
- tvres->tv_usec = tmptv1->tv_usec + 1000000 - tmptv2->tv_usec;
- /* 不存在借位的情况 */
- } else {
- /* 对应的秒和微秒分别做差 */
- tvres->tv_sec = tmptv1->tv_sec - tmptv2->tv_sec;
- tvres->tv_usec = tmptv1->tv_usec - tmptv2->tv_usec;
- }
- }
- /* 时间值比较大小 */
- int TimeCompare(const struct timeval *tv1, const struct timeval *tv2)
- {
- /* 如果秒值不一致则秒值大者较大 */
- if (tv1->tv_sec > tv2->tv_sec)
- return 1;
- else if (tv1->tv_sec < tv2->tv_sec)
- return -1;
- /* 秒值相同的,微秒值较大者较大 */
- else if (tv1->tv_usec > tv2->tv_usec)
- return 1;
- else if (tv1->tv_usec < tv2->tv_usec)
- return -1;
- /* 秒值和微秒值皆相同者等值 */
- else
- return 0;
- }
- /* 打印时间 */
- void PrintTimeval(const char *str, const struct timeval *tv)
- {
- printf("%s = %ld sec %ld usec\n", str, tv->tv_sec, tv->tv_usec);
- }
程序会提示你输入空循环的次数,2.7GHz的CPU在空闲的时候使用300至500时大约会1秒钟显示一次时间。数值越大显示时间的间隔越长,根据你的计算机的具体情况而定。此外输出的数据也各你当前系统状态而定。
0 0
- Linux 计时器 函数
- Linux 计时器 函数
- Linux 计时器 函数
- Linux 计时器 函数
- 函数计时器
- Linux计时器
- linux计时器
- 自学Linux--Linux计时器
- GTK 计时器函数
- SetTimer函数计时器
- Linux进程的计时器和间隔计时器
- Linux进程的计时器和间隔计时器
- (笔记)linux下的真实计时器、虚拟计时器、实用计时器
- Linux定时器(计时器)
- Linux定时器(计时器)
- linux 计时器 timer
- linux c 语言 计时器
- linux计时器之posix_timer
- linux文件权限
- SSH2框架配置文件
- java找回密码发送到邮箱
- Block的语法
- VS2013常用快捷键
- Linux 计时器 函数
- highcharts:图表部分属性列表
- Java---30---IO(一)
- 用MySQL数据库来处理中英文取首字母排序
- java nio
- android TextView上添单击事件,跳转到另一个Activity
- Runloop 解释笔记
- Linux进程的计时器和间隔计时器
- C++ Primer第四版习题--3.18