3

我正在编写一个线程库,并且在调度线程时我需要知道它们已经准备好多长时间。每个 Thread 实例都有一个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)。

有任何想法吗?谢谢!

4

3 回答 3

5

您应该将结果作为 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

于 2012-04-24T15:36:59.747 回答
1

在我的计算机上,所有tv_sectv_usec1000000都是有符号的 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值执行。

您可以(但不必)将您的更改doubleuint64_t. 这取决于你。

于 2012-04-24T16:06:50.643 回答
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;
于 2018-04-02T09:08:30.480 回答