在1.10节,我们描述过三次我们可以测量:挂钟时间、用户CPU时间和系统CPU时间。任何进程可以调用times函数来为它自己和任何终止的子程序来获得这些值。
- #include <sys/times.h>
- clock_t times(struct tms *buf);
- 如果成功返回逝去的挂钟时间,错误返回-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结构体打印这些值:
- #include <sys/times.h>
- #include <stdio.h>
- #include <unistd.h>
- static void pr_times(clock_t, struct tms *, struct tms *);
- static void do_cmd(char *);
- void pr_exit(int status);
- int
- main(int argc, char *argv[])
- {
- int i;
- setbuf(stdout, NULL);
- for (i = 1; i < argc; i++)
- do_cmd(argv[i]); /* once for each command-line arg */
- exit(0);
- }
- static void
- do_cmd(char *cmd) /* execute and time the "cmd" */
- {
- struct tms tmsstart, tmsend;
- clock_t start, end;
- int status;
- printf("\ncommand: %s\n", cmd);
- if ((start = times(&tmsstart)) == -1) { /* starting values */
- printf("times error\n");
- exit(1);
- }
- if ((status = system(cmd)) < 0) { /* execute command */
- printf("system() error");
- exit(1);
- }
- if ((end = times(&tmsend)) == -1) { /* ending values */
- printf("times error\n");
- exit(1);
- }
- pr_times(end-start, &tmsstart, &tmsend);
- pr_exit(status);
- }
- static void
- pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend)
- {
- static long clktck = 0;
- if (clktck == 0) /* fetch clock ticks per second first time */
- if ((clktck = sysconf(_SC_CLK_TCK)) < 0) {
- printf("sysconf error\n");
- exit(1);
- }
- printf(" real: %7.2f\n", real / (double) clktck);
- printf(" user: %7.2f\n",
- (tmsend->tms_utime - tmsstart->tms_utime) / (double) clktck);
- printf(" sys: %7.2f\n",
- (tmsend->tms_stime - tmsstart->tms_stime) / (double) clktck);
- printf(" child user: %7.2f\n",
- (tmsend->tms_cutime - tmsstart->tms_cutime) / (double) clktck);
- printf(" child sys: %7.2f\n",
- (tmsend->tms_cstime - tmsstart->tms_cstime) / (double) clktck);
- }
运行的结果为:
$ ./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
阅读(1083) | 评论(0) | 转发(0) |