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()
的执行上下文。