timestamp in c with milliseconds precision

橙三吉。 提交于 2019-12-12 12:40:08

问题


I'm relatively new to C programming and I'm working on a project which needs to be very time accurate; therefore I tried to write something to create a timestamp with milliseconds precision.

It seems to work but my question is whether this way is the right way, or is there a much easier way? Here is my code:

#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;
}

回答1:


The following code seems likely to provide millisecond granularity:

#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;
}

This is based on http://msdn.microsoft.com/en-us/library/windows/desktop/ms724950%28v=vs.85%29.aspx. The above code snippet was tested with CYGWIN on Windows 7.

For Windows 8, there is GetSystemTimePreciseAsFileTime, which "retrieves the current system date and time with the highest possible level of precision (<1us)."

Your original approach would probably be ok 99.99% of the time (ignoring one minor bug, described below). Your approach is:

  • Wait for the next second to start, by repeatedly calling time() until the value changes.
  • Save that value from time().
  • Save the value from clock().
  • Calculate all subsequent times using the current value of clock() and the two saved values.

Your minor bug was that you had the first two steps reversed.

But even with this fixed, this is not guaranteed to work 100%, because there is no atomicity. Two problems:

  • Your code loops time() until you are into the next second. But how far are you into it? It could be 1/2 a second, or even several seconds (e.g. if you are running a debugger with a breakpoint).

  • Then you call clock(). But this saved value has to 'match' the saved value of time(). If these two calls are almost instantaneous, as they usually are, then this is fine. But Windows (and Linux) time-slice, and so there is no guarantee.

Another issue is the granularity of clock. If CLOCKS_PER_SEC is 1000, as seems to be the case on your system, then of course the best you can do is 1 msec. But it can be worse than that: on Unix systems it is typically 15 msecs. You could improve this by replacing clock with QueryPerformanceCounter(), as in the answer to timespec equivalent for windows, but this may be otiose, given the first two problems.




回答2:


Clock periods are not at all guaranteed to be in milliseconds. You need to explicitly convert the output of clock() to milliseconds.

t1 = clock();
// do something
t2 = clock();
long millis = (t2 - t1) * (1000.0 / CLOCKS_PER_SEC);



回答3:


Since you are on Windows, why don't you just use Sleep()?



来源:https://stackoverflow.com/questions/21888229/timestamp-in-c-with-milliseconds-precision

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!