文章结构:
概念与函数
CPU时间(CPU TIME)是指当应用进程启动后,占用CPU进行计算所进行的时间绝对值,或叫时间点。如果进程进入中断、挂起、休眠等行为时,是不占用CPU的,所以CPU时间并不会跟着增加,且进程恢复运行后所获得的CPU时间值与运行中断之前的时间值是连续的,并不会因为运行的暂停而导致CPU时间的跳跃。这是和普通的日常时间值不一样的点。另一个不同的点是CPU时间并不是以秒为单位的,而是处理器的时钟周期为单位。
获取CPU时间的函数#include <time.h>
clock_t clock(void)
该函数返回CPU时间,CPU时间并不一定会从0开始,所以要计算进程的一段代码所消耗的CPU时间记录需要在代码前后获取各自的起始和终止CPU时间,两者之差即为所消耗的CPU时间,即为处理器耗时(Processor Time)。
要将clock_t
转换为秒数,需要除以宏CLOCKS_PER_SEC
生成的值,即为秒数。但要注意的是由于在不同的系统中clock_t
或CLOCKS_PER_SEC
可能为int
也可能为浮点型数值,所以在计算时需要在计算过程中并其强制转换为double
以保证计算结果。
另外需要注意的是clock()
函数所返回的值在32位系统上每72分钟就会恢复原始值一次。clock()
如果执行错误,则会返回-1。
获取CPU时间与更详细的进程时间还有另外一个函数:#include <sys/times.h>
clock_t times(struct tms *buf);
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 */
};
函数times()
会将进程的处理器时间分类。在参数tms
中各字段含义为:tms_utime
:用户层处理器耗时。即执行该进程的实现代码所消耗的CPU时间和。tms_stime
:系统层处理器耗时。即该进程实现的代码调用了系统内核代码,由这部分内核代码执行所消耗的CPU时间和。tms_cutime
:子进程用户层处理器耗时。即如果当前进程通过调用system()
或fork()
函数导致产生新的子进程(数量前后可能为多个),则记录所有子进程的实现代码所消耗的CPU时间和。tms_cstime
:子进程用户层处理器耗时。即如果当前进程通过调用system()
或fork()
函数导致产生新的子进程(数量前后可能为多个),则记录所有子进程实现的代码调用了系统内核代码,由这部分内核代码执行所消耗的CPU时间和。
函数times()
所返回的值单位都是时钟滴哒(clock tick)
数。要获取每秒钟的时钟滴哒可以调用函数sysconf(_SC_CLK_TCK);
来获取。为了保证精度,在计算耗时时,也要在计算过程中将参与的计算值转换为double
以保证计算结果。
函数times()
所返回的值表示过去某个时间点到函数调用此刻的时间消耗长度。所以进程的中断、挂起、休眠等行为仍会导致返回值的持续增加。这一点是与clock()
的不同所在。通常也利用这个特点来计算进程的前后自然时间耗时时长。
在计算时长方面,times()
通过精确到秒以下(可能是毫秒,因为是double类型的计算),但缺点是参数buf
必须不为空;