Подтвердить что ты не робот

Получить временную метку в C в микросекундах?

Как получить метку времени в микросекундах в C?

Я пытаюсь сделать:

struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_usec;

Но это возвращает некоторое бессмысленное значение, которое, если я получу две метки времени, второй может быть меньше или больше, чем первый (второй должен всегда быть больше). Можно ли было бы преобразовать магическое целое, возвращаемое gettimeofday, в нормальное число, с которым можно фактически работать?

4b9b3361

Ответ 1

Вам нужно добавить и секунды:

unsigned long time_in_micros = 1000000 * tv.tv_sec + tv.tv_usec;

Обратите внимание, что это будет продолжаться только около 2 32/10 6= ~ 4295 секунд, или примерно 71 минут (в обычной 32-разрядной системе).

Ответ 2

У вас есть два варианта получения микросекундной метки времени. Первый (и лучший) выбор - использовать тип timeval напрямую:

struct timeval GetTimeStamp() {
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return tv;
}

Второй, и для меня менее желательным, выбор состоит в том, чтобы построить uint64_t из timeval:

uint64_t GetTimeStamp() {
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return tv.tv_sec*(uint64_t)1000000+tv.tv_usec;
}

Ответ 3

struct timeval содержит два компонента: второй и микросекунду. Временная метка с точностью до микросекунды представлена ​​в виде секунд с момента сохранения в поле tv_sec и дробных микросекунд в tv_usec. Таким образом, вы не можете просто игнорировать tv_sec и ожидать разумных результатов.

Если вы используете Linux или * BSD, вы можете использовать timersub() для вычитания двух значений struct timeval, которые могут быть такими, какие вы хотите.

Ответ 4

Но это возвращает некоторую бессмыслицу что, если я получу две метки времени, второй может быть меньше или больше чем первый (второй должен всегда быть больше).

Почему вы так думаете? Значение, вероятно, ОК. В той же ситуации, что и в секундах и минутах - когда вы измеряете время в минутах и ​​секундах, количество секунд перекатывается до нуля, когда оно достигает шестидесяти.

Чтобы преобразовать возвращаемое значение в "линейный" номер, вы можете умножить количество секунд и добавить микросекунды. Но если я правильно считаю, один год составляет около 1e6 * 60 * 60 * 24 * 360 мкс, и это означает, что вам нужно больше 32 бит для сохранения результата:

$ perl -E '$_=1e6*60*60*24*360; say int log($_)/log(2)'
44

Вероятно, это одна из причин разделения исходного возвращаемого значения на две части.

Ответ 5

timespec_get от C11 возвращается к наносекундам, округленное до разрешения реализации.

#include <time.h>
struct timespec ts;
timespec_get(&ts, TIME_UTC);
struct timespec {
    time_t   tv_sec;        /* seconds */
    long     tv_nsec;       /* nanoseconds */
};

Подробнее здесь: fooobar.com/questions/9684/...

Ответ 6

Сначала нам нужно знать диапазон микросекунд, т.е. от 000_000 до 999_999 (1000000 микросекунд равно 1 секунде). tv.tv_usec вернет значение от 0 до 999999 не 000000 до 999999, поэтому при использовании его в секундах мы можем получить 2.1 секунды вместо 2.000001 секунд, потому что, когда говорить только о tv_usec 000001, по существу, 1.  Лучше, если вы введете

if(tv.tv_usec<10)
{
 printf("00000");
} 
else if(tv.tv_usec<100&&tv.tv_usec>9)// i.e. 2digits
{
 printf("0000");
}

и т.д.

Ответ 7

используйте неподписанный длинный длинный (то есть 64-разрядный блок) для представления системного времени:

typedef unsigned long long u64;

u64 u64useconds;
struct timeval tv;

gettimeofday(&tv,NULL);
u64useconds = (1000000*tv.tv_sec) + tv.tv_usec;