2012-04-24 91 views
2

我正在写一个线程库,在调度线程时,我需要知道他们已经准备了多久。每个线程实例都有一个timeval _timeInReady场,当我把一个实例来就绪队列我调用这个函数:当我想检查当前_timeInReady值我称之为gettimeofday返回一个负值

void Thread::startTiming() { 
    gettimeofday(&_timeInReady, NULL); 
} 

double Thread::getTimeInReady() const { 
    return TIME(_timeInReady.tv_sec,_timeInReady.tv_usec); 
} 

在哪里TIME是#define TIME(a,b) ((a*1000000) + b)这样我就可以得到总时间(以微秒为单位)。

我的问题是,由于某些原因,当我在一段时间后检查该字段时,我得到了疯狂的负值(例如-10293843)。

任何想法?谢谢!

+0

您是否注意到,您认为自己有负数?如果是打印声明,请显示它。如果这是一个调试器检查,请告诉我们更多关于这一点的信息。 – 2012-04-24 15:56:57

+0

这是一个调试器,日食 – yotamoo 2012-04-24 16:01:26

回答

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

在我的计算机上,所有tv_sec,tv_usec1000000都是带有符号32位的数字。当被要求保存大于2^31左右的数字时,签名的32位值溢出。

其结果是,此表达式:

((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。这取决于你。