C:Windows和其他操作系统中clock()的不同实现?

时间:2014-11-27 21:21:09

标签: c linux windows macos clock

我必须为大学编写一个非常简单的控制台程序,必须测量输入所需的时间。

因此我在前面和clock()来电后使用了fgets()。在我的Windows计算机上运行时,它工作得很好。然而,当我在我的朋友Mac-Book和Linux-PC上运行时,它会产生非常小的结果(只有几微秒的时间)。

我在所有3个操作系统上尝试了以下代码:

#include <stdio.h>
#include <time.h>
#include <unistd.h>

void main()
{
    clock_t t;

    printf("Sleeping for a bit\n");

    t = clock();

    // Alternatively some fgets(...)
    usleep(999999);

    t = clock() - t;

    printf("Processor time spent: %lf", ((double)t) / CLOCKS_PER_SEC);
}

在Windows上,输出显示1秒(或使用fgets时输入的时间),另外两个操作系统显示的时间不超过0秒。

现在我的问题是为什么在这些操作系统上clock()的实现存在这样的差异。对于Windows来说,当线程处于休眠/等待状态时,时钟似乎仍在滴答作响,但对于Linux和Mac则不然?

编辑: 感谢你们到目前为止的答案,所以这只是微软错误的实现。

有人可以回答我的上一个问题:

还有一种方法可以测量我想要使用C标准库在所有3个系统上测量的内容,因为clock()似乎只在Windows上以这种方式工作吗?

4 个答案:

答案 0 :(得分:2)

您在Microsoft的C运行时遇到a known bug。即使行为不符合任何ISO C标准,也不会被修复。来自错误报告:

  

但是,我们选择避免​​重新实现clock(),使得它可能返回时间值比每秒物理秒快一秒,因为这种变化会根据之前的行为默默地破坏程序(我们期望在那里很多这样的节目。)

答案 1 :(得分:1)

如果我们在Mac OS X上clock() look at the source code,我们会看到它是使用getrusage实现的,并且会读取ru_utime + ru_stime。这两个字段measure CPU time used by the process (or by the system, on behalf of the process)。这意味着如果usleep(或fgets)导致操作系统交换不同的程序执行,直到发生某事,那么任何实时数量(也称为“挂墙时间”,如“墙”)时钟“)已过去不计入clock()在Mac OS X上返回的值。您可以深入挖掘并在Linux中找到类似的内容。

但是,在Windows上,自流程开始以来clock() returns the amount of wall time已过去。

在纯C中,我不知道OS X,Linux和Windows上可用的函数将以亚秒精度返回挂起时间(time.h相当有限)。您在Windows上有GetSystemTimeAsFileTime,它将以100ns的切片返回时间,而来自BSD的gettimeofday将返回精确到微秒的时间。

如果您接受第二精度,则可以使用time(NULL)

如果C ++是一个选项,你可以使用std::chrono中的一个时钟来获得所需的精度。

答案 2 :(得分:1)

我建议您尝试创建自己的 clock() 函数。如果你想使用它,我已经创建了这个类似于 Linux 上的 clock() 函数的简单函数:

clock_t clock_unix_like_systems(void)
{   
    struct timespec current_time;
    if (clock_gettime(CLOCK_BOOTTIME,&current_time) != 0) return -1;
    return current_time.tv_sec * CLOCKS_PER_SEC + current_time.tv_nsec /(1000000000 /CLOCKS_PER_SEC); 
}

注意: 记住关于这个函数的两件事,1)你可以改变变量的类型。 2) 您可以使用 errno 全局变量来描述有关特定操作失败原因的详细信息。

举个例子,如果你想从头开始创建 Arduino 的 delay() 函数,你可以使用它,就像在下一个例子中一样:

    int delay(int millis)
    {   
        if (millis < 0)
        {
            printf("Time must be positive");
        

    return -1;
    }
    clock_t start;int  finish;
    long int compare = (long int) millis * 1000;
    start = clock_unix_like_systems();
    while(finish <= compare) 
    {
        finish = (long int) (clock_unix_like_systems() - start);

    }
    return 0;
}

我希望这会有所帮助。

答案 3 :(得分:0)

在Linux上,您应该阅读time(7)。它建议使用最近MacOSX(以及Linux)上应该存在的POSIX 2001 clock_gettime。在Linux上运行不太旧的硬件(例如,不到6年的笔记本电脑或台式机),clock_gettime提供了良好的准确性,通常为几十微秒或更好。它给出了秒和纳秒的测量值(在struct timespec中),但我不认为纳秒数字是非常准确的。

确实,clock(3)被告知符合......

  

C89,C99,POSIX.1-2001。 POSIX要求CLOCKS_PER_SEC等于          1000000独立于实际分辨率。

最后,几个框架库提供了函数(包装目标特定的系统函数)来测量时间。查看POCO(使用C ++)或Glib(来自GT中的GTK&amp; Gnome)。