我正在编写一个线程库,在调度线程时我需要知道它们已经准备好了多长时间。每个Thread实例都有一个timeval _timeInReady
字段,当我将一个实例推送到就绪队列时,我调用这个函数:
void Thread::startTiming() {
gettimeofday(&_timeInReady, NULL);
}
当我想检查当前_timeInReady
值时,我打电话:
double Thread::getTimeInReady() const {
return TIME(_timeInReady.tv_sec,_timeInReady.tv_usec);
}
其中TIME为#define TIME(a,b) ((a*1000000) + b)
因此我得到的总时间以微秒为单位。
我的问题是,出于某种原因,当我在一段时间后检查该字段时,我会得到疯狂的负值(例如-10293843)。
有什么想法吗?谢谢!
答案 0 :(得分:4)
您应该将结果作为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
。
答案 1 :(得分:1)
在我的计算机上,tv_sec
,tv_usec
和1000000
的所有内容都是带符号的32位数量。当要求保持大于2 ^ 31左右的数字时,有符号的32位值会溢出。
结果,这个表达式:
((x.tv_sec*1000000) + x.tv_usec)
将在2^31 / 10^6
秒内溢出,或大约2,147秒。只要你的程序只在短于35分钟的时间间隔内处理,你应该没问题。
如果您想表示值> = 35分钟,请尝试将#define
替换为:
#define TIME(a,b) ((a*1000000ull) + b)
通过标准促销活动,此更改将导致您使用unsigned long long
值执行所有数学运算。
您可以(但不一定)将double
更改为uint64_t
。随你(由你决定。
答案 2 :(得分:0)
尝试使用这个来获取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;