可以度量的三个时间:
- 墙上时钟时间
- 用户 CPU 时间
- 系统 CPU 时间
任一进程可以调用 times 函数获得自己以及已终止之进程的上述值。
#include <sys/times.h>
clock_t times(struct tms * buf);
// 函数返回值:若成功,返回流逝的墙上时钟时间(以时钟滴答数为单位)
// 若出错,返回 -1
我们来看一下 struct tms 结构体
struct tms {
clock_t tms_utime; /* user time */
clock_t tms_stime; /* system time */
clock_t tms_cutime; /* user time of children */
clock_t tms_cstime; /* system time of children */
};
所有由此函数返回的 clock_t 值都用 _SC_CLK_TCK 转换成秒数。
我们来写个小程序,他把每个命令行参数作为 shell 命令串执行,对每个命令计时,并打印从 tms 结构取得的值。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/times.h>
#include <sys/wait.h>
static void do_cmd(char *);
static void pr_times(clock_t, struct tms *, struct tms *);
static void print_exit(int status);
int main(int argc, char *argv[])
{
if(argc < 2)
{
printf("Usage: ./timing_process \" process\"");
exit(1);
}
setbuf(stdout, NULL);
for(int i = 1; i < argc; ++i)
{
do_cmd(argv[i]);
}
return 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)
{
perror("times error");
exit(2);
}
if((status = system(cmd)) < 0)
{
perror("system() error");
exit(3);
}
if((end = times(&tmsend)) == -1)
{
perror("times error");
exit(2);
}
pr_times(end - start, &tmsstart, &tmsend);
print_exit(status);
}
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)
{
perror("sysconf error");
}
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);
}
static void print_exit(int status)
{
if(WIFEXITED(status))
{
printf("normal termination, exit status = %d\n", WEXITSTATUS(status));
}
else if(WIFSIGNALED(status))
{
printf("abnormal termination, signal number = %d%s\n", WTERMSIG(status),
#ifdef WCOREDUMP
WCOREDUMP(status) ? "core file generated" : "");
#else
"");
#endif
}
else if(WIFSTOPPED(status))
{
printf("child stopped, signal number = %d\n", WIFSTOPPED(status));
}
}
运行此程序可以得到: