我相对较新的C编程和即时工作,目前在一个项目,这需要非常准确的时间,因此我试图写一些东西,以毫秒的精度创build一个时间戳。 这似乎工作,但我的问题是这样的方式是正确的方式还是有一个更简单的方法? 这是我的代码:
#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 。 上面的代码片段在Windows 7上使用CYGWIN进行了测试。
对于Windows 8,有GetSystemTimePreciseAsFileTime ,它“以最高可能的精度级别(<1us)检索当前系统日期和时间”。
你原来的方法可能会是99.99%的时间(忽略一个小错误,下面描述)。 你的方法是:
time()
直到值改变。 time()
保存该值。 clock()
的值。 clock()
的当前值和两个保存的值计算所有后续时间。 你的小错误是,你有前两步倒过来。
但是,即使这个固定的,这也不能保证100%的工作,因为没有原子性。 两个问题:
你的代码循环time()
直到你进入下一秒。 但是你到底有多远 ? 它可能是1/2秒,甚至几秒钟(例如,如果您运行带有断点的调试器)。
然后你叫clock()
。 但是这个保存的值必须与time()
的保存值“匹配”。 如果这两个电话几乎是瞬时的,就像他们通常那样 ,那么这很好。 但Windows(和Linux)时间片等等是不能保证的。
另一个问题是clock
的粒度。 如果CLOCKS_PER_SEC是1000,就好像你的系统是这种情况,那么你最好能做的是1毫秒。 但是它可能比这更糟糕:在Unix系统上它通常是15毫秒。 你可以通过用QueryPerformanceCounter(),
来替代clock
来改善这个问题, 就像windows对timepec的回答一样 ,但是这可能不是最好的。
时钟周期毫无保证地以毫秒为单位。 您需要将clock()的输出显式转换为毫秒。
t1 = clock(); // do something t2 = clock(); long millis = (t2 - t1) * (1000.0 / CLOCKS_PER_SEC);
既然你在Windows上,为什么不使用Sleep()呢?