【问题标题】:Mismatch in timing时间不匹配
【发布时间】:2012-05-23 13:02:52
【问题描述】:
struct timeval start, end, duration;
gettimeofday(&start, NULL);

res = curl_easy_perform(curl);

gettimeofday(&end, NULL);
timersub(&end, &start, &duration);

tm* startTime = localtime(&start.tv_sec);
tm* endTime = localtime(&end.tv_sec);
char buf[64];
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", startTime);
char buf2[64];
strftime(buf2, sizeof(buf2), "%Y-%m-%d %H:%M:%S", endTime);

ofstream timeFile;
timeFile.open ("timingSheet.txt");
timeFile << fixed << showpoint;
timeFile << setprecision(6);
timeFile << "Duration: " << duration.tv_sec << "." << duration.tv_usec << " seconds \n";
timeFile << "Start time: " <<  buf <<"." << start.tv_usec << "\n";
timeFile << "End time: " <<  buf2 <<"." << end.tv_usec << "\n";
timeFile.close();

当我运行这段代码时,我得到了这个输出:

Duration: 3.462243 seconds 
Start time: 2012-05-15 17:14:07.432613
End time: 2012-05-15 17:14:07.894856

令我困惑的是,持续时间值与开始和结束时间不匹配。这两个日期仅相差微秒。是否有一个原因?

谢谢!

【问题讨论】:

  • timersub() 会发生什么?
  • timersub() 不应影响开始或结束。它只是一个获取两个 timeval 的差异并将这些值放在 duration 中的函数。
  • 请贴出代码。如果它不改变startend,那么它一定会错误地计算duration
  • linux.die.net/man/3/timersub 我不确定代码实际在哪里。
  • # define timersub(a, b, result) \ do { \ (result)-&gt;tv_sec = (a)-&gt;tv_sec - (b)-&gt;tv_sec; \ (result)-&gt;tv_usec = (a)-&gt;tv_usec - (b)-&gt;tv_usec; \ if ((result)-&gt;tv_usec &lt; 0) { \ --(result)-&gt;tv_sec; \ (result)-&gt;tv_usec += 1000000; \ } \ } while (0) #endif /* BSD */

标签: c++ timing strftime timeval


【解决方案1】:

localtime 返回一个静态分配的缓冲区,你调用它两次,所以 StartTime 和 EndTime 是相同的。您需要在每次调用后直接将其复制到另一个缓冲区中。

tm* startTime = localtime(&start.tv_sec); 
char buf[64]; 
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", startTime); 

tm* endTime = localtime(&end.tv_sec); 
char buf2[64]; 
strftime(buf2, sizeof(buf2), "%Y-%m-%d %H:%M:%S", endTime); 

编辑:你也可以这样写:

tm* pTimeBuf = localtime(&start.tv_sec); 
char buf[64]; 
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", pTimeBuf); 

localtime(&end.tv_sec); // NB. I don't store th return value (since I have it already)
char buf2[64]; 
strftime(buf2, sizeof(buf2), "%Y-%m-%d %H:%M:%S", pTimeBuf); 

【讨论】:

  • 问题不在于 strftime(),而在于 localtime()。 localtime 返回一个指向内部内存的指针。每次调用本地时间时都会重用该内存。您的变量 starttime 和 endtime 具有相同的指针值,实际上您可以摆脱一个(我会更新我的答案,以便您明白我的意思)。
  • localtime() 的更安全且无疑更好的变体是 AwesomeNix 的回答所指出的。
  • 最近下载了这个(不记得从哪里下载了),目前正在阅读:Linux Programming Interface - A Linux and UNIX System Programming Handbook (No Starch, 2010, 1593272200).pdf
  • 有趣的是他们会这样实现它。我正在使用它,我的回答更有意义,但仍然关闭!我得到了这些结果:Duration: 2.759294 seconds Start time: 2012-05-16 13:12:41.39434 End time: 2012-05-16 13:12:43.798728 我正在测试如果我不使用 timersub 是否能得到更一致的结果。
  • @Dave :我认为 tv_usecs 的显示不正确。 41.39434 应该显示为 41.039434
【解决方案2】:

我同意 Edwin 的观点,只是稍作修改,最好使用线程安全版本 localtime_r 而不是本地时间

struct tm startTime,endTime;
memset(&startTime,0,sizeof(struct tm)); //Advisable but not necessary
memset(&endTime,0,sizeof(struct tm)); //Advisable but not necessary
localtime_r(&start.tv_sec, &startTime);
localtime_r(&end.tv_sec, &endTime);

【讨论】:

    猜你喜欢
    • 2017-01-31
    • 1970-01-01
    • 2011-12-20
    • 2021-02-26
    • 2013-09-19
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多