首页 > 解决方案 > C 编程时间和时钟功能

问题描述

我正在研究 Linux 4.4 内核(Ubuntu)并比较times函数(在 sys/times.h 中)和clock函数(在 time.h 中)之间的输出。

根据手册页,times应该从某个任意时间开始返回程序使用的“CPU时间”(但该任意时间应该在函数调用之间保持一致)。

同样根据手册页,clock应该返回程序使用的处理器时间的近似值。

下面的代码使用这些调用中的每一个来打印执行某些任意工作所需的时间。似乎这些时间应该排成一行,但它们似乎总是相差 10,000 倍。

#include <stdio.h>
#include <unistd.h>
#include <sys/times.h>
#include <time.h>

int main() {
    struct tms times_start, times_end;
    clock_t times_start_retval, times_end_retval;
    clock_t clock_start, clock_end;

    /* clock called first and last, so estimates using "clock" should be
       slightly longer than estimates using "times" */
    if((clock_start = clock()) == -1) {
        perror("starting clock");
        return -1;
    }

    if((times_start_retval = times(&times_start)) == -1) {
        perror("starting times");
        return -1;
    }

    for(int i = 100000000; i; i--); // do work

    if((times_end_retval = times(&times_end)) == -1) {
        perror("ending timer");
        return -1;
    }

    if((clock_end = clock()) == -1) {
        perror("ending clock");
        return -1;
    }

    printf("Times using the clock system call\n");
    printf("clock start: %li\nclock end: %li\n", clock_start, clock_end);
    printf("elapsed: %li\n\n", clock_end - clock_start);

    printf("Times using the times system call\n");
    printf("System start: %li\nUser start: %li, start retval: %li\n",
        times_start.tms_stime, times_start.tms_utime, times_start_retval);
    printf("System end:   %li\nUser end:   %li, end retval:   %li\n",
        times_end.tms_stime, times_end.tms_utime, times_end_retval);
    printf("elapsed: %li\n\n", times_end_retval - times_start_retval);

    return 0;
}

结果是:

Times using the clock system call
clock start: 5016
clock end: 321323
elapsed: 316307

Times using the times system call
System start: 0
User start: 0, start retval: 1733759140
System end:   0
User end:   31, end retval:   1733759172
elapsed: 32

根据描述,这些似乎应该同时返回。他们不是的事实让我想知道潜在的可移植性问题。为什么这些时间不同?

标签: cunixtime

解决方案


也许我只是需要问这个问题。我想我刚刚在The Linux Programming Interface (Kerrisk 2011, pg 206-207) 中找到了答案。答案似乎是“CPU 时间”以两种不同的方式测量。

times 返回以“时钟滴答”测量的时间。每秒的时钟滴答数可以使用sysconf(_SC_CLK_TCK)and 对于我的系统是 100 来检索。所以每个时钟滴答大约是 1/100 秒。

时钟返回以“每秒时钟数”测量的时间。显然对于 Unix 兼容的系统,这应该总是 1,000,000。当我从 time.h 头文件中打印 CLOCKS_PER_SEC 时,这就是我在系统上得到的。

要获得秒数,我必须将clock返回值除以 1,000,000,或者将times返回值除以 100。这意味着对于每个“时钟滴答”,有 10,000 个“时钟”。这似乎解释了我看到的 10,000 差异的因素。


推荐阅读