UNIX系统中struct tms 分析《转载》
资源利用情况和执行次数
Wall clock time (墙上时钟时间) 流逝的时间
User CPU time (用户CPU时间) 进程花在执行用户模式(非内核模式)代码上的时间总量
System CPU time (系统CPU时间) 花在执行内核代码上的时间总量
通过调用times 或 getrusage 可以获得这信息, 前者能给出细致时间,后者可以给出更多信息,进程的利用情况, 比如它的内存占用量只能从getrusage调用获得。
1> 进程计时
#include <sys/times.h>
clock_t time(struct tms *buf);
times返回系统自举后经过的时间滴答数, 也称为墙上时钟时间。
[root@localhost c]# cat get_times.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/times.h>
#include <time.h>
#include <unistd.h>
void doit(char *, clock_t);
int main(void)
{
clock_t start, end;
struct tms t_start, t_end;
start = times(&t_start);
system("grep the /usr/share/doc/* > /dev/null ");
end=times(&t_end);
doit("elpapsed", end - start);
puts("parent times");
doit("\tuser CPU", t_end.tms_utime);
doit("\tsys CPU", t_end.tms_stime);
puts("child times");
doit("\tuser CPU", t_end.tms_cutime);
doit("\tsys CPU", t_end.tms_cstime);
exit(EXIT_SUCCESS);
}
void doit(char *str, clock_t time)
{
/* Get clock ticks/second */
long tps = sysconf(_SC_CLK_TCK);
printf("%s: %6.2f secs \n", str, (float)time/tps);
}
[root@localhost c]# ./get_times
elpapsed: 0.05 secs
parent times
user CPU: 0.00 secs
sys CPU: 0.00 secs
child times
user CPU: 0.02 secs
sys CPU: 0.00 secs
当程序调用system函数时, 它先产生一个子进程, 然后是子进程而不是父进程完成所有工作并消耗了CPU时间
进程的执行时间0.05并不等于用户CPU时间和系统CPU时间之和 0.02秒。 原因是子进程执行的grep操作是I/O密集型而非CPU密集型的操作。 它扫描了这里讨论所使用的系统上的多个文件, 缺少的0.03秒全部用从硬盘读取数据。
times返回的时间是相对而非绝对时间(系统自举后经过的时钟滴答数), 所以要让它有实用价值, 就必须做两次测量并使用它们的差值。 这就引入了 流逝时间, 或者称为墙上时钟时间。 resusg1通过把起止的时钟滴答数分别保存在start和end中来做到这一点。 另一种进程计时值可从<sys/times.h>中定义的tms结构中获得。 tms结构保存着一个进程及其子进程的当前CPU时间。
struct tms{
clock_t tms_utime; /* user cpu time */
clock_t tms_stime; /* system cpu time */
clock_t tms_cutime; /* user cpu time of children */
clock_t tms_cstime; /* system cpu time of children */
};
注: 这些时间都是时钟滴答数,而不是秒数。 使用sysconf函数能把时钟滴答数转为秒数, 这个函数把它的参数转换成在运行时定义的系统限制值或选项值, 返回类型为long
_SC_CLK_TCK 是定义每秒钟有多少滴答的宏。
这个程序的关键处是doit函数, 它接受一个字符串指针和一个clock_t类型的值,然后计算并输出进程每部分实际的计时信息。