gettimeofday возвращает отрицательное значение
Я пишу библиотеку потоков, и при планировании потоков мне нужно знать, как долго они были готовы. Каждый экземпляр потока имеет timeval _timeInReady
поле, и когда я помещаю экземпляр в готовую очередь, я вызываю эту функцию:
void Thread::startTiming() {
gettimeofday(&_timeInReady, NULL);
}
Когда я хочу проверить текущий _timeInReady
значение я называю:
double Thread::getTimeInReady() const {
return TIME(_timeInReady.tv_sec,_timeInReady.tv_usec);
}
Где ВРЕМЯ #define TIME(a,b) ((a*1000000) + b)
Так что я получаю общее время в микросекундах.
Моя проблема в том, что по какой-то причине я получаю сумасшедшие отрицательные значения (например, -10293843), когда проверяю это поле через некоторое время.
Есть идеи? Спасибо!
3 ответа
Вы должны вернуть результат в виде 64-разрядного целого числа без знака, так как вы хотите получить целочисленный результат в микросекундах, а не дробную секунду (что подразумевает возврат double
):
unsigned long long Thread::getTimeInReady() const
{
return (unsigned long long)_timeInReady.tv_sec * 1000000ULL +
(unsigned long long)_timeInReady.tv_usec;
}
Ваша система может иметь uint64_t
который является более кратким, чем unsigned long long
или вы могли бы typedef
Это.
На моем компьютере все tv_sec
, tv_usec
, а также 1000000
подписаны 32-битные количества. 32-битные значения со знаком переполняются, когда их просят сохранить число больше 2^31 или около того.
В результате это выражение:
((x.tv_sec*1000000) + x.tv_usec)
переполнится в 2^31 / 10^6
секунд или около 2147 секунд. Пока ваша программа работает только с интервалами менее 35 минут, все будет в порядке.
Если вы хотите представить значения>= 35 минут, попробуйте заменить #define
с этим:
#define TIME(a,b) ((a*1000000ull) + b)
Благодаря стандартным акциям это изменение приведет к выполнению всех ваших математических заданий с unsigned long long
ценности.
Вы можете, но не обязательно, менять свой double
в uint64_t
, Это зависит от вас.
Попробуйте это, чтобы получить время для 32-битных систем:-
struct timeval time;
gettimeofday(&time, NULL);
unsigned long long secTime = ((unsigned long long)time.tv_sec) * 1000 + ((unsigned long long)(time.tv_usec))/1000;