Получить временную метку в C в микросекундах?
Как получить метку времени в микросекундах в C?
Я пытаюсь сделать:
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_usec;
Но это возвращает некоторое бессмысленное значение, которое, если я получу две метки времени, второй может быть меньше или больше, чем первый (второй должен всегда быть больше). Можно ли было бы преобразовать магическое целое, возвращаемое gettimeofday, в нормальное число, с которым можно фактически работать?
Ответы
Ответ 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;