我必须为大学编写一个非常简单的控制台程序,必须测量输入所需的时间。
因此我在前面和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上以这种方式工作吗?
答案 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,¤t_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)。