clock_gettime() returns bad results (Debian wheezy

2019-08-06 02:19发布

I am attempting to use clock_gettime() to monitor elapsed time. However it returns bad results.

I tested it with the following:

#include <time.h>
#include <iostream>
#include <math.h>

using namespace std;

int main()
{
    // Time vars for calculation.
    int ns;

    // Initial struct.
    timespec tt;

    // Get starting time.
    clock_gettime(CLOCK_MONOTONIC,&tt);
    int ns_start = tt.tv_nsec;
    int s_start = tt.tv_sec;

    // Base for second wrap around.
    int ns_base = 1000e6 - ns_start;

    while(true)
    {
        cin.ignore();

        // Get time.
        clock_gettime(CLOCK_MONOTONIC,&tt);

        // Implement/calculate wrap around.
        if(tt.tv_nsec >= ns_start) ns = tt.tv_nsec - ns_start;
        else ns = tt.tv_nsec + ns_base;

        // Display result.
        cout << "Time Passed:\ts: " << tt.tv_sec-s_start << " ms: " << round(ns/1e6) << endl;
    }

    return 0;
}

When I hold any key for a while I get a similar result:

Time Passed:    s: 1 ms: 833



Time Passed:    s: 2 ms: 308
Time Passed:    s: 2 ms: 354
Time Passed:    s: 2 ms: 415


Time Passed:    s: 2 ms: 459
Time Passed:    s: 2 ms: 511


Time Passed:    s: 2 ms: 566
Time Passed:    s: 2 ms: 613


Time Passed:    s: 2 ms: 661
Time Passed:    s: 2 ms: 712


Time Passed:    s: 2 ms: 762
Time Passed:    s: 2 ms: 813


Time Passed:    s: 2 ms: 861
Time Passed:    s: 2 ms: 920 // crap starts here


Time Passed:    s: 3 ms: 970
Time Passed:    s: 3 ms: 20


Time Passed:    s: 3 ms: 69
Time Passed:    s: 3 ms: 124


Time Passed:    s: 3 ms: 171
Time Passed:    s: 3 ms: 226


Time Passed:    s: 3 ms: 272
Time Passed:    s: 3 ms: 329


Time Passed:    s: 3 ms: 372
Time Passed:    s: 3 ms: 429


Time Passed:    s: 3 ms: 474
Time Passed:    s: 3 ms: 528


Time Passed:    s: 3 ms: 576
Time Passed:    s: 3 ms: 632


Time Passed:    s: 3 ms: 679
Time Passed:    s: 3 ms: 736


Time Passed:    s: 3 ms: 782
Time Passed:    s: 3 ms: 835


Time Passed:    s: 3 ms: 880
Time Passed:    s: 4 ms: 939


Time Passed:    s: 4 ms: 982
Time Passed:    s: 4 ms: 38


Time Passed:    s: 4 ms: 84
Time Passed:    s: 4 ms: 143


Time Passed:    s: 4 ms: 188
Time Passed:    s: 4 ms: 244


Time Passed:    s: 4 ms: 291
Time Passed:    s: 4 ms: 348


Time Passed:    s: 4 ms: 391
Time Passed:    s: 4 ms: 448


Time Passed:    s: 4 ms: 493
Time Passed:    s: 4 ms: 549


Time Passed:    s: 4 ms: 594
Time Passed:    s: 4 ms: 650

Time Passed:    s: 4 ms: 696

Time Passed:    s: 6 ms: 259

Time Passed:    s: 7 ms: 989

It should be obvious by looking at the numbers that results are messed up at the point of comment.

Anyone has any ideas as to why this is and how to fix it?

标签: c++ linux timer
1条回答
够拽才男人
2楼-- · 2019-08-06 03:07

Imagine the timer starts at 1.999 seconds. At 2.001 seconds, your code would say that 1 second and 2 ms have elapsed, when really it should be zero seconds and 2 ms. This is because you're subtracting the starting second from the current second, even if the nanosecond part hasn't passed its starting value.

You had the right idea with the nanosecond wraparound. Let's extend that to keep the seconds from getting ahead of the correct value. Here's one way to do it:

#include <time.h>
#include <iostream>
#include <math.h>

using namespace std;

int main()
{
    // Time vars for calculation.
    int ns;
    int s;

    // Initial struct.
    timespec tt;

    // Get starting time.
    clock_gettime(CLOCK_MONOTONIC,&tt);
    int ns_start = tt.tv_nsec;
    int s_start = tt.tv_sec;

    // Base for second wrap around.
    int ns_base = 1000e6 - ns_start;

    while(true)
    {
        cin.ignore();

        // Get time.
        clock_gettime(CLOCK_MONOTONIC,&tt);

        // Implement/calculate wrap around.
        if(tt.tv_nsec >= ns_start)
        {
            ns = tt.tv_nsec - ns_start;
            s = tt.tv_sec - s_start;
        }
        else
        {
            ns = tt.tv_nsec + ns_base;
            s = tt.tv_sec - s_start - 1;
        }

        // Display result.
        cout << "Time Passed:\ts: " << s << " ms: " << round(ns/1e6) << endl;
    }

    return 0;
}
查看更多
登录 后发表回答