Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1727198
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: 系统运维

2012-03-29 13:52:28

在1.10节,我们描述过三次我们可以测量:挂钟时间、用户CPU时间和系统CPU时间。任何进程可以调用times函数来为它自己和任何终止的子程序来获得这些值。



  1. #include <sys/times.h>

  2. clock_t times(struct tms *buf);

  3. 如果成功返回逝去的挂钟时间,错误返回-1


这个函数填充由buf指向的tms结构体:
struct tms {
  clock_t tms_utime;  /* user CPU time */
  clock_t tms_stime;  /* system CPU time */
  clock_t tms_cutime;  /* user CPU time, terminated children */
  clock_t tms_cstime;  /* system CPU time, terminated children */
};


注意这个结构体没有包含任何挂钟时间的测量。相反,函数每次被调用时都返回这个挂钟时间。这个值从过去的一个任意时间测量,所以我们不能使用它的绝对值。 相反,我们使用它的相对值。例如,我们调用times并保存返回值。一段时间后,我们再次调用times并将新的返回值减去更早的返回值。这个差值就是挂 钟返回时间。(虽然不太可能,但对于一个长时间运行的进程还是有可能溢出挂钟时间。)


为子进程提供的两个结构体域只包含了我们用wait、waitid或waitpid等待过的子进程的值。


这个函数返回的所有clock_t值都使用每秒的嘀嗒数--sysconf返回的_SC_CLK_TCK值--转换成秒。


多数实现提供了getrusage函数。这个函数返回CPU时间和14个其它指明资源使用的值。历史上,这个函数在BSD操作系统上起源,所以继承BSD的实现通常支持比其它实现更多的域。


下面的代码执行每个命令行参数,作为一个外壳命令字符串,为这个命令计时并从tms结构体打印这些值:



  1. #include <sys/times.h>
  2. #include <stdio.h>
  3. #include <unistd.h>

  4. static void pr_times(clock_t, struct tms *, struct tms *);
  5. static void do_cmd(char *);
  6. void pr_exit(int status);

  7. int
  8. main(int argc, char *argv[])
  9. {
  10.     int i;
  11.     setbuf(stdout, NULL);
  12.     for (i = 1; i < argc; i++)
  13.         do_cmd(argv[i]); /* once for each command-line arg */
  14.     exit(0);
  15. }

  16. static void
  17. do_cmd(char *cmd) /* execute and time the "cmd" */
  18. {
  19.     struct tms tmsstart, tmsend;
  20.     clock_t start, end;
  21.     int status;

  22.     printf("\ncommand: %s\n", cmd);

  23.     if ((start = times(&tmsstart)) == -1) { /* starting values */
  24.         printf("times error\n");
  25.         exit(1);
  26.     }

  27.     if ((status = system(cmd)) < 0) { /* execute command */
  28.         printf("system() error");
  29.         exit(1);
  30.     }

  31.     if ((end = times(&tmsend)) == -1) { /* ending values */
  32.         printf("times error\n");
  33.         exit(1);
  34.     }

  35.     pr_times(end-start, &tmsstart, &tmsend);
  36.     pr_exit(status);
  37. }

  38. static void
  39. pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend)
  40. {
  41.     static long clktck = 0;
  42.     if (clktck == 0) /* fetch clock ticks per second first time */
  43.         if ((clktck = sysconf(_SC_CLK_TCK)) < 0) {
  44.             printf("sysconf error\n");
  45.             exit(1);
  46.         }
  47.     printf(" real: %7.2f\n", real / (double) clktck);
  48.     printf(" user: %7.2f\n",
  49.         (tmsend->tms_utime - tmsstart->tms_utime) / (double) clktck);
  50.     printf(" sys: %7.2f\n",
  51.         (tmsend->tms_stime - tmsstart->tms_stime) / (double) clktck);
  52.     printf(" child user: %7.2f\n",
  53.         (tmsend->tms_cutime - tmsstart->tms_cutime) / (double) clktck);
  54.     printf(" child sys: %7.2f\n",
  55.         (tmsend->tms_cstime - tmsstart->tms_cstime) / (double) clktck);
  56. }


运行的结果为:
$ ./a.out "sleep 5" "date"

command: sleep 5
 real:    5.01
 user:    0.00
 sys:    0.00
 child user:    0.00
 child sys:    0.00
normal termination, exit status = 0

command: date
2012年 03月 05日 星期一 18:40:52 CST
 real:    0.00
 user:    0.00
 sys:    0.00
 child user:    0.00
 child sys:    0.00
normal termination, exit status = 0
阅读(1026) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~