web-dev-qa-db-ja.com

c timevalとtimespec

精度の違いは別として、struct timevalstruct timespecの違いは何ですか? µs(ミリ秒など)よりも低い精度が必要な場合、なぜ一方を他方よりも使用するのですか?

私のコンパイラ(ARMのgcc):

/* POSIX.1b structure for a time value.  This is like a `struct timeval' but
   has nanoseconds instead of microseconds.  */
struct timespec
  {
    __time_t tv_sec;        /* Seconds.  */
    __syscall_slong_t tv_nsec;  /* Nanoseconds.  */
  };

/* A time value that is accurate to the nearest
   microsecond but also has a range of years.  */
struct timeval
  {
    __time_t tv_sec;        /* Seconds.  */
    __suseconds_t tv_usec;  /* Microseconds.  */
  };

__syscall_slong_t__suseconds_tの両方が「長い単語」として定義されています。

13
Julien-L

それは本当にAPIの[互換性]の問題だと思います。 pselect() および clock_gettime() のようなPOSIX-y呼び出しは、struct timespecを使用します。 utimes() のようなさまざまなファイルシステム呼び出し、および gettimeofday() および select() のようないくつかのLinux呼び出し=、struct timevalを使用します。いくつかのmanページから広く一般化すると、struct timevalはBSDのレガシーを持っているのに対し、struct timespecはPOSIXだと思います。

間隔測定を行っている場合、clock_gettime()からの追加の精度を活用しない理由はありません。ただし、測定精度を制限するのは通常ヘッダーファイルではなくハードウェアであることを認識してください。表示目的で100万で割ると、1000で割るよりも良くも悪くもありません。また、 Mac OS Xはclock_gettime() をサポートしていません。

ただし、多くのファイル時間操作を行う場合は、utimes()などのAPIで使用されているstruct timevalを使用する方が理にかなっている可能性があります。 struct timevalには、Linux、BSD、Mac OS Xの比較関数もいくつかあります。 timercmp()timersub()(ここでも、manページを参照してください)。

構造そのものではなく、使用する予定のAPIに基づいて決定します。 (または、必要に応じて、変換メソッドを含むラッパークラスを記述します。)

16
lyngvi

どちらもPOSIX.1-2001用にAFAIKで定義されているため、移植性の観点からは、どちらを使用してもかまいません。最も簡単な答えは、呼び出すAPIに必要なものを使用することです。

struct timevalを使用すると、プラットフォームに依存したサイズのメリットが得られます。

タイプsuseconds_tは、少なくとも[-1、1000000]の範囲の値を格納できる符号付き整数タイプです。

struct timespecでは、2番目のメンバーのタイプはlongです。 32ビットプラットフォームでは、intsuseconds_t要件を満たすのに十分です。ただし、64ビットシステムでは、time_tは通常64ビットであるため、構造は強制的に16バイトにパディングされます。だからサイズのメリットは-ありそうもない。

3
user2371524

個人的にはどちらも使用していません。時間を単純なint64_tとして表現することをお勧めします。これにより、時間の計算が簡単になり、必要に応じてstruct timevalまたはstruct timespecに戻すことも問題ありません。ナノ秒の精度が必要な場合でも、int64_tは、ほぼ585年のスパンを表すことができます。ミリ秒しか必要ない場合は、5億8500万年近くのスパンがあります。

1
Mecki