1

現在、 で使用する絶対時間を取得しようとしていpthread_mutex_timedlockます。timevalfromgettimeofdayをに追加してからtimespec、任意の時間を追加する必要があることはわかっています。

以下は機能しますが、このような大きな数で乗算するとオーバーフローする可能性があります。

これを行うためのより良い方法はありますか (ミリ秒単位で時間が与えられます):

struct timespec ts;
struct timeval now;
gettimeofday(&now, nullptr);

ts.tv_sec = now.tv_sec + milliseconds / 1000;
ts.tv_nsec = now.tv_usec * 1000000000 * (milliseconds % 1000);

ts.tv_sec += ts.tv_nsec / (1000000000);
ts.tv_nsec %= (1000000000);

上記では、指定された時間を現在の時間に加算して、絶対時間を取得しています。

私の代替コードは次のとおりです。

void timeval_to_timespec(struct timeval* tv, struct timespec* ts)
{
    ts->tv_sec = tv->tv_sec;
    ts->tv_nsec = tv->tv_usec * 1000;
}

struct timespec add_timespec(struct timespec* a, struct timespec* b)
{
    struct timespec result = {a->tv_sec + b->tv_sec, b->tv_nsec + b->tv_nsec};
    if(result.tv_nsec >= 1000000000)
    {
        result.tv_nsec -= 1000000000;
        ++result.tv_sec;
    }
    return result;
}

//Convert the milliseconds to timespec.
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds - (ts.tv_sec * 1000)) * 1000000;

//Convert the current time(timeval) to timespec.
timeval_to_timespec(&now, &spec_now);

ts = add_timespec(&ts, &spec_now); //add the milliseconds to the current time.

上記を行うためのより良い方法があるかどうか疑問に思っています。別のコードを使用したくないのですが、前のコードはあまり安全ではないようで、モジュロが好きではありません。

アイデア?

4

1 に答える 1

1

最初のアプローチは実際には合理的ですが、定数でいくつかのタイプミスやエラーが発生しています。

このアプローチはどうですか:

ts.tv_sec = now.tv_sec + milliseconds / 1000;
ts.tv_nsec = now.tv_usec * 1000 // 1000 ns per us, not a million!
             + (milliseconds % 1000) * 1000000 // a million ns per ms.
ts.tv_sec += ts.tv_nsec / 1000000000;
ts.tv_nsec %= 1000000000;

now.tv_usec * 1000は 999,999,000 を超えず、999,000,000 を超えないため、2 番目の加算が 32 ビットの int をオーバーフローする危険はあり(milliseconds % 1000) * 1000000ません。したがって、合計は最大で 1,998,999,000 になります (最後の 2 行で運ばれる秒数は常に 0 です)。または 1)。

于 2015-02-16T21:45:07.670 に答える