c中的时间戳(以毫秒为单位) [英] timestamp in c with milliseconds precision

查看:639
本文介绍了c中的时间戳(以毫秒为单位)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对C编程比较陌生,我正在从事一个项目,该项目需要非常精确的时间;因此,我尝试编写一些东西来创建毫秒级的时间戳.

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

推荐答案

以下代码似乎可以提供毫秒级的粒度:

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

这基于 http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms724950%28v=vs.85%29.aspx .上面的代码段已在Windows 7上使用CYGWIN进行了测试.

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.

对于Windows 8,有

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

您的原始方法可能在99.99%的时间内都可以(忽略一个较小的错误,如下所述).您的方法是:

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

  • 通过重复调用time()直到值更改,等待下一秒开始.
  • time()保存该值.
  • 保存clock()中的值.
  • 使用clock()的当前值和两个保存的值计算所有后续时间.
  • 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.

但是即使修复了这个问题,也不能保证100%正常工作,因为没有原子性.两个问题:

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

  • 您的代码将循环执行time(),直到进入下一秒为止.但是您有多远?可能是1/2秒,甚至几秒钟(例如,如果您正在运行带有断点的调试器).

  • 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).

然后您呼叫clock().但是此保存的值必须匹配" time()的保存值. 如果这两个调用几乎是瞬时的,就像它们通常是 一样,那么这很好.但是Windows(和Linux)的时间片,因此不能保证.

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.

另一个问题是clock的粒度.如果CLOCKS_PER_SEC是1000,这在您的系统上似乎是这样,那么当然,您可以做的最好是1毫秒.但是,情况可能会更糟:在Unix系统上,通常为15毫秒.您可以通过用QueryPerformanceCounter(),替换clock来改善此情况,如 Windows的timespec等效的答案,但是考虑到前两个问题,这可能很简单.

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.

这篇关于c中的时间戳(以毫秒为单位)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆