我对 C 编程比较陌生,我正在开发一个需要非常精确的时间的项目;因此我尝试写一些东西来创建毫秒精度的时间戳。
这似乎有效,但我的问题是这种方法是否正确,或者是否有更简单的方法?这是我的代码:
#include<stdio.h>
#include<time.h>
void wait(int milliseconds)
{
clock_t start = clock();
while(1) if(clock() - start >= milliseconds) break;
}
int main()
{
time_t now;
clock_t milli;
int waitMillSec = 2800, seconds, milliseconds = 0;
struct tm * ptm;
now = time(NULL);
ptm = gmtime ( &now );
printf("time before: %d:%d:%d:%d\n",ptm->tm_hour,ptm->tm_min,ptm->tm_sec, milliseconds );
/* wait until next full second */
while(now == time(NULL));
milli = clock();
/* DO SOMETHING HERE */
/* for testing wait a user define period */
wait(waitMillSec);
milli = clock() - milli;
/*create timestamp with milliseconds precision */
seconds = milli/CLOCKS_PER_SEC;
milliseconds = milli%CLOCKS_PER_SEC;
now = now + seconds;
ptm = gmtime( &now );
printf("time after: %d:%d:%d:%d\n",ptm->tm_hour,ptm->tm_min,ptm->tm_sec, milliseconds );
return 0;
}
以下代码似乎可能提供毫秒粒度:
#include <windows.h>
#include <stdio.h>
int main(void) {
SYSTEMTIME t;
GetSystemTime(&t); // or GetLocalTime(&t)
printf("The system time is: %02d:%02d:%02d.%03d\n",
t.wHour, t.wMinute, t.wSecond, t.wMilliseconds);
return 0;
}
这是基于http://msdn.microsoft.com/en-us/library/windows/desktop/ms724950%28v=vs.85%29.aspx http://msdn.microsoft.com/en-us/library/windows/desktop/ms724950%28v=vs.85%29.aspx。上述代码片段在 Windows 7 上使用 CYGWIN 进行了测试。
对于 Windows 8,有获取系统时间精确为文件时间 http://msdn.microsoft.com/en-us/library/windows/desktop/hh706895%28v=vs.85%29.aspx,它“以尽可能高的精度(
您原来的方法可能在 99.99% 的情况下都可以(忽略一个小错误,如下所述)。你的做法是:
- 等待下一秒开始,通过重复调用
time()
直到值发生变化。
- 保存该值
time()
.
- 保存值来自
clock()
.
- 使用当前值计算所有后续时间
clock()
以及两个保存的值。
你的小错误是你把前两个步骤颠倒了。
但即使修复了这个问题,也不能保证 100% 有效,因为不存在原子性。两个问题:
另一个问题是粒度clock
。如果 CLOCKS_PER_SEC 为 1000(您的系统似乎就是这种情况),那么当然您能做的最好是 1 毫秒。但情况可能比这更糟:在 Unix 系统上通常为 15 毫秒。您可以通过替换来改进这一点clock
with QueryPerformanceCounter(),
正如在答案中Windows 的 timespec 等效项 https://stackoverflow.com/questions/8583308/timespec-equivalent-for-windows,但是考虑到前两个问题,这可能是多余的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)