在Linux上获取毫秒级时间的C++方法——clock()似乎无法正常工作

105
在Windows上,clock()返回毫秒级的时间,但在我正在使用的这个Linux框,它将其舍入到最近的1000,因此精度仅到"秒"级别而不是毫秒级别。
我找到了一个使用Qt解决的方法,使用QTime类来实例化一个对象,在调用start()之后调用elapsed()以获取经过的毫秒数。
我有点幸运,因为我一开始就在使用Qt,但我想要一个不依赖第三方库的解决方案。
难道没有标准的方法吗?
更新
请不要推荐Boost..
如果Boost和Qt都可以做到这一点,那么肯定不是魔法,一定有一些标准的东西可以使用!

2
关于编辑 - 但以可移植的方式进行编辑有些麻烦。 - Anonymous
相关:https://dev59.com/vF4c5IYBdhLWcg3wCGb2为什么clock被认为是不好的。 - Cole Tobin
16个回答

1

gettimeofday - 问题在于如果您更改硬件时钟(例如使用NTP),它将具有较低的值

Boost - 对于此项目不可用

clock() - 通常返回4字节整数,这意味着它的容量较低,并且经过一段时间后会返回负数。

我更喜欢创建自己的类并每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。

不要使用alarm或ualarm函数,当您的进程遇到重负荷时,精度会很低。


1
在POSIX标准中,clock的返回值是以CLOCKS_PER_SEC符号定义的,实现可以以任何方便的方式定义它。在Linux下,我使用times()函数运行良好。

0

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

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

成员函数:

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循环所占用的总执行时间。这个时间包括操作系统由于多任务而切换main()的执行上下文。


0
作为更新,似乎在Windows上clock()测量的是挂钟时间(精度为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的具体版本。


0

我喜欢Hola Soy方法,不使用gettimeofday()。在一个运行中的服务器上,管理员更改了时区。时钟被更新以显示相同(正确)的本地值。这导致time()和gettimeofday()函数向后移动2个小时,并且某些服务中的所有时间戳都停滞了。


0

我更喜欢 Boost Timer library,因为它简单易用,但如果你不想使用第三方库,使用 clock() 也是合理的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接