任一进程都可使用 times 函数来获得它自己以及终止子进程的 3 个时间:墙上时钟时间、用户 CPU 时间和系统 CPU 时间。
注意,墙上时钟时间是作为返回值得到的,它是相对于过去某一时刻度量的。tms 结构中两个针对子进程的字段包含了此进程用 wait 函数族已等待到的各子进程的值。所有由此函数返回的 clock_t 值都用 _SC_CLK_TCK(由 sysconf 函数返回的每秒时钟滴答数)转换成秒数(多数实现还提供了 getrusage 函数,该函数返回由 CPU 时间以及指示资源使用情况的另外 14 个值)。
下列程序会对每个 shell 命令计时,并打印从 tms 结构取得的值。
运行结果:
前两个命令的执行时间足够快避免了以可报告的精度记录 CPU 时间,但第三个命令运行了一个处理时间足够长的程序来表面所有的 CPU 时间都出现在子进程中,而 shell 和命令正是在子进程中执行的。
#include <sys/times.h>
clock_t times(struct tms *buf);
/* 返回值:若成功,返回流逝的墙上时钟时间(以时钟滴答数为单位);否则,返回 -1 */
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
};
注意,墙上时钟时间是作为返回值得到的,它是相对于过去某一时刻度量的。tms 结构中两个针对子进程的字段包含了此进程用 wait 函数族已等待到的各子进程的值。所有由此函数返回的 clock_t 值都用 _SC_CLK_TCK(由 sysconf 函数返回的每秒时钟滴答数)转换成秒数(多数实现还提供了 getrusage 函数,该函数返回由 CPU 时间以及指示资源使用情况的另外 14 个值)。
下列程序会对每个 shell 命令计时,并打印从 tms 结构取得的值。
#include <stdlib.h>
#include <stdio.h>
#include <sys/times.h>
static void pr_times(clock_t, struct tms *, struct tms *);
static void do_cmd(char *);
int main(int argc, char *argv[]){
int i;
setbuf(stdout, NULL);
for(i=1; i<argc; i++)
do_cmd(argv[i]);
exit(0);
}
static void do_cmd(char *cmd){
struct tms tmsstart, tmsend;
clock_t start, end;
int status;
printf("\ncommand: %s\n", cmd);
if((start=times(&tmsstart)) == -1)
printf("times 1 error\n");
if((status=system(cmd)) < 0)
printf("system error\n");
if((end=times(&tmsend)) == -1)
printf("times 2 error\n");
pr_times(end-start, &tmsstart, &tmsend);
}
static void
pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend){
static long clktck = 0;
if(clktck == 0)
if((clktck=sysconf(_SC_CLK_TCK)) < 0)
printf("sysconf error\n");
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);
}
运行结果:
$ ./timesDemo.out "sleep 5" "date>/dev/null" "man bash>/dev/null"
command: sleep 5
real: 5.01
user: 0.00
sys: 0.00
child user: 0.00
child sys: 0.00
command: date>/dev/null
real: 0.00
user: 0.00
sys: 0.00
child user: 0.00
child sys: 0.00
command: man bash>/dev/null
real: 0.28
user: 0.00
sys: 0.00
child user: 0.23
child sys: 0.02
前两个命令的执行时间足够快避免了以可报告的精度记录 CPU 时间,但第三个命令运行了一个处理时间足够长的程序来表面所有的 CPU 时间都出现在子进程中,而 shell 和命令正是在子进程中执行的。