【问题标题】:ctime not getting time difference of start/end of loop correctlyctime 没有正确获取循环开始/结束的时间差
【发布时间】:2019-07-07 18:04:37
【问题描述】:

我正在尝试在executionTime 指定的确切时间执行循环。我正在使用ctime 来获取这个时间,并且我需要它在几毫秒的精度内(我相信它是)。一旦该循环运行指定的执行时间,它应该会中断。

我的问题是执行时间为 0.5,打印的结果是 1。经过进一步测试,我的程序似乎将执行时间四舍五入到最接近的整数。所以对于 4.5executionTime,打印的执行时间是 5.0000000。我的代码如下。我不确定这个错误来自哪里。

#include <time.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 

int main() 
{
    float  executionTime = 4.5; 
    int i;
    float  timeDifference = -1;  
    time_t t1;
    time_t t2;

    t1 = time(0);

    for (i = 0; i < 1000000000; i++) 
    {
        t2 = time(0); 

        timeDifference = difftime(t2, t1); 

        if (timeDifference >= executionTime) 
        { 
            break; 
        }

    }

    printf("time difference is: %f\n", timeDifference); 

    return 0; 

}

新版本尝试使用clock_gettime。这个版本的问题是在循环内由于某种原因达到执行时间时永远不会中断。

#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#define BILLION 1E9 

int main()
{
    float  executionTime = 4.5;
    int i;
    float  elapsedTime = -1;

    struct timespec start;
    struct timespec stop;

    //Get starting time 
    clock_gettime(CLOCK_REALTIME, &start);

    for (i = 0; i < 1000000000; i++)
    {
        //Get current time
        clock_gettime(CLOCK_REALTIME, &stop);

        elapsedTime = ((stop.tv_sec - start.tv_sec) + (stop.tv_nsec - start.tv_nsec)) / BILLION;

        if (elapsedTime >= executionTime)
        {
            break;
        }
    }

    printf("time difference is: %f\n", elapsedTime);

    return 0;

}

【问题讨论】:

  • this question 看来,C 不保证time_t 的类型,因此可能是整数类型被传递给difftime,导致时间差为整数秒.
  • 强烈建议(因为time()的粒度为1秒)使用函数setitimer(),该函数用于设置间隔并在该间隔到期时设置信号
  • @user3629249 是的,我放弃了time() 的用法,现在正在使用第二部分更新版本(在 OG 帖子中进一步向下)。我现在使用clock_gettime()

标签: c linux ctime


【解决方案1】:

clock_gettime 可用于获得更高的准确性。
使用大于 0 的值调用delay 来设置延迟时间,然后使用 -1 来检查经过的时间。
在 main 中调用 clock_gettime 将在 main 中给出经过的时间。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>

#define BILLION  1E9

int delay ( double seconds)
{
    static double usec = 0.0;
    double elapsed = 0.0;
    static struct timespec start;
    struct timespec stop;

    if ( 0.0 <= seconds) {
        usec = seconds;
        clock_gettime ( CLOCK_REALTIME, &start);
        return 0;
    }
    clock_gettime ( CLOCK_REALTIME, &stop);
    elapsed = difftime ( stop.tv_sec, start.tv_sec);
    elapsed += ( stop.tv_nsec - start.tv_nsec) / BILLION;
    if ( ( elapsed < usec)) {
        return 1;
    }
    return 0;
}

int main() {

    double  executionTime = 4.5;
    int i;
    double  timeDifference = -1;
    struct timespec end;
    struct timespec begin;

    clock_gettime ( CLOCK_REALTIME, &begin);
    delay( executionTime);//call to set time

    for (i = 0; i < 1000000000; i++)
    {
        if ( !delay( -1)) {//call to check elapsed time
            break;
        }
    }
    clock_gettime ( CLOCK_REALTIME, &end);
    timeDifference = difftime ( end.tv_sec, begin.tv_sec);
    timeDifference += ( end.tv_nsec - begin.tv_nsec) / BILLION;

    printf("time difference is: %f\n", timeDifference);

    return 0;
}

【讨论】:

  • 您可以根据您的示例查看我在 OG 帖子中的编辑版本吗?循环在 4.5 秒后没有终止。我相信我正在比较类似于您的方式的时间(只是没有那么多移动的部分)。
【解决方案2】:

time() 返回最接近的秒,difftime() 返回它们的差。所以基本上这个函数计算整数的差异。要获得更准确的估计,您可以使用clock()

time_t 用于测量日历时间

int main() 
{
    float  executionTime = 1.3; 
    int i;
    double  timeDifference = 1.0;  
    clock_t t1;
    clock_t t2;

    t1 = clock();

    for (i = 0; i < 1000000000; i++) 
    {
        timeDifference = (double)(clock() - t1) / CLOCKS_PER_SEC;

        if (timeDifference >= executionTime) 
        { 
            break; 
        }

    }

    printf("time difference is: %.9g\n", timeDifference); 

    return 0; 

}

【讨论】:

  • 我不认为我会使用您的示例,因为 Linux 在很多地方都使用 timespec,并且坚持使用该标准可能会有所帮助。但是,您的帖子适用于其他情况:)
猜你喜欢
  • 1970-01-01
  • 2020-11-09
  • 2019-05-05
  • 1970-01-01
  • 2016-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多