C ++在Linux上获取毫秒时间 – clock()似乎不能正常工作

在Windows上, clock()以毫秒为单位返回时间,但是在我正在使用的这个Linux机器上,它把它舍入到最接近的1000,所以精度只能达到“秒”级而不是毫秒级。

我使用QTime类find了一个Qt的解决scheme,实例化一个对象并调用start() ,然后调用elapsed()来获取经过的毫秒数。

我很幸运,因为我正在和Qt合作,但是我想要一个不依赖于第三方库的解决scheme,

有没有标准的方法来做到这一点?

UPDATE

请不要推荐Boost ..

如果Boost和Qt能够做到这一点,那肯定不是魔术,他们必须要有一些标准的东西!

您可以在方法的开始和结束处使用gettimeofday,然后区分两个返回结构。 你会得到如下结构:

 struct timeval { time_t tv_sec; suseconds_t tv_usec; } 
 #include <sys/time.h> #include <stdio.h> #include <unistd.h> int main() { struct timeval start, end; long mtime, seconds, useconds; gettimeofday(&start, NULL); usleep(2000); gettimeofday(&end, NULL); seconds = end.tv_sec - start.tv_sec; useconds = end.tv_usec - start.tv_usec; mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5; printf("Elapsed time: %ld milliseconds\n", mtime); return 0; } 

请注意, clock不会测量挂钟时间。 这意味着如果你的程序需要5秒钟, clock不一定会测量5秒钟,但可能更多(你的程序可能运行多个线程,因此可能消耗更多的CPU比实时)或更less。 它测量所使用的CPU时间的近似值。 要看到差异考虑这个代码

 #include <iostream> #include <ctime> #include <unistd.h> int main() { std::clock_t a = std::clock(); sleep(5); // sleep 5s std::clock_t b = std::clock(); std::cout << "difference: " << (b - a) << std::endl; return 0; } 

它在我的系统上输出

 $ difference: 0 

因为我们所做的只是睡觉而不使用任何CPU时间! 但是,使用gettimeofday我们得到我们想要的(?)

 #include <iostream> #include <ctime> #include <unistd.h> #include <sys/time.h> int main() { timeval a; timeval b; gettimeofday(&a, 0); sleep(5); // sleep 5s gettimeofday(&b, 0); std::cout << "difference: " << (b.tv_sec - a.tv_sec) << std::endl; return 0; } 

输出在我的系统上

 $ difference: 5 

如果您需要更高的精度但想要获得CPU时间 ,则可以考虑使用getrusage函数。

我也推荐Boost提供的工具。 无论是提到的升压计时器,或破解Boost.DateTime的东西或沙箱中有新的build议库 – Boost.Chrono :这最后一个将是定时器的替代品,将具有以下function:

  • C ++ 0x标准库的时间公用程序包括:
    • 类模板duration
    • 类模板time_point
    • 钟:
      • system_clock
      • monotonic_clock
      • high_resolution_clock
  • 类模板timer ,带有typedefs:
    • system_timer
    • monotonic_timer
    • high_resolution_timer
  • 处理时钟和定时器:
    • process_clock ,捕获真实,用户CPU和系统CPU时间。
    • process_timer ,捕获实时,用户CPU和系统CPU时间。
    • run_timer ,方便报告| process_timer | 结果。
  • C ++ 0x标准库的编译时有理算术。

这是function列表的来源

我写了一个基于CTT的答案的Timer类。 它可以通过以下方式使用:

 Timer timer = Timer(); timer.start(); /* perform task */ double duration = timer.stop(); timer.printTime(duration); 

这是它的实现:

 #include <stdio.h> #include <stdlib.h> #include <sys/time.h> using namespace std; class Timer { private: timeval startTime; public: void start(){ gettimeofday(&startTime, NULL); } double stop(){ timeval endTime; long seconds, useconds; double duration; gettimeofday(&endTime, NULL); seconds = endTime.tv_sec - startTime.tv_sec; useconds = endTime.tv_usec - startTime.tv_usec; duration = seconds + useconds/1000000.0; return duration; } static void printTime(double duration){ printf("%5.6f seconds\n", duration); } }; 

如果您不需要将代码移植到旧的unice中,则可以使用clock_gettime(),它将以纳秒为单位给出时间(如果您的处理器支持该分辨率)。 这是POSIX,但是从2001年开始。

时钟()经常是一个非常糟糕的决议。 如果你想在毫秒级测量时间,另一种方法是使用clock_gettime(),正如在这个问题中所解释的那样。

(请记住,您需要在Linux上连接-lrt)。

用C ++ 11和std::chrono::high_resolution_clock你可以这样做:

 #include <iostream> #include <chrono> #include <thread> typedef std::chrono::high_resolution_clock Clock; int main() { std::chrono::milliseconds three_milliseconds{3}; auto t1 = Clock::now(); std::this_thread::sleep_for(three_milliseconds); auto t2 = Clock::now(); std::cout << "Delta t2-t1: " << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << " milliseconds" << std::endl; } 

输出:

 Delta t2-t1: 3 milliseconds 

链接到演示: http : //cpp.sh/2zdtu

clock()不会在linux上返回毫秒或秒。 通常clock()在linux系统上返回微秒。 解释clock()返回的值的正确方法是将其除以CLOCKS_PER_SEC来计算已经过了多less时间。

这应该工作…在Mac上testing…

 #include <stdio.h> #include <sys/time.h> int main() { struct timeval tv; struct timezone tz; struct tm *tm; gettimeofday(&tv,&tz); tm=localtime(&tv.tv_sec); printf("StartTime: %d:%02d:%02d %d \n", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec); } 

是的…运行两次,然后减去…

在POSIX中,标准clock的返回值是用CLOCKS_PER_SEC符号定义的,实现可以用任何便利的方式自由定义。 在Linux下,我用times()函数祝你好运。

gettimeofday – 问题是,如果你改变你的硬件时钟,可能会有更低的值(例如用NTP)Boost – 不能用于这个项目clock() – 通常返回一个4字节的整数,这意味着它的容量低,一段时间后它返回负数。

我更喜欢创build我自己的类,每10毫秒更新一次,所以这种方式更加灵活,我甚至可以改进它,使用户。

 class MyAlarm { static int64_t tiempo; static bool running; public: static int64_t getTime() {return tiempo;}; static void callback( int sig){ if(running){ tiempo+=10L; } } static void run(){ running = true;} }; int64_t MyAlarm::tiempo = 0L; bool MyAlarm::running = false; 

刷新它我使用setitimer:

 int main(){ struct sigaction sa; struct itimerval timer; MyAlarm::run(); memset (&sa, 0, sizeof (sa)); sa.sa_handler = &MyAlarm::callback; sigaction (SIGALRM, &sa, NULL); timer.it_value.tv_sec = 0; timer.it_value.tv_usec = 10000; timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 10000; setitimer (ITIMER_REAL, &timer, NULL); ..... 

看看setitimer和ITIMER_VIRTUAL和ITIMER_REAL。

不要使用警报或报警function,当你的过程艰苦工作时,精度会很低。

我比较喜欢Boost Timer库 ,但是如果你不想使用third-parrty库,那么使用clock()似乎是合理的。

作为一个更新,在Windows时钟()上测量挂钟时间(具有CLOCKS_PER_SEC精度)

  http://msdn.microsoft.com/en-us/library/4e2ess30(VS.71).aspx 

而在Linux上,它测量当前进程使用的内核之间的CPU时间

 http://www.manpagez.com/man/3/clock 

和(看起来像原来的海报一样)实际上比CLOCKS_PER_SEC的精度要低,不过也许这取决于Linux的特定版本。

我喜欢不使用gettimeofday()的Hola Soy方法。 它发生在我运行的服务器上pipe理员改变了时区。 时钟已更新以显示相同(正确)的本地值。 这导致函数time()和gettimeofday()移位2个小时,某些服务中的所有时间戳都卡住了。

我用timeb编写了一个C++类。

 #include <sys/timeb.h> class msTimer { public: msTimer(); void restart(); float elapsedMs(); private: timeb t_start; }; 

会员function:

 msTimer::msTimer() { restart(); } void msTimer::restart() { ftime(&t_start); } float msTimer::elapsedMs() { timeb t_now; ftime(&t_now); return (float)(t_now.time - t_start.time) * 1000.0f + (float)(t_now.millitm - t_start.millitm); } 

使用示例:

 #include <cstdlib> #include <iostream> using namespace std; int main(int argc, char** argv) { msTimer t; for (int i = 0; i < 5000000; i++) ; std::cout << t.elapsedMs() << endl; return 0; } 

我的电脑输出是'19'。 msTimer类的精确度为毫秒级。 在上面的使用示例中,跟踪由for -loop占用的总执行时间。 这次包括操作系统由于多任务处理而切换进入和离开main()的执行上下文。