2013-06-14 22 views
8

私はclock_gettime()コマンドを使用し、そこから取得したtimespecに一定のミリ秒を追加しようとしています。私はちょうどこれをすることはできますかtimespecは、tv_nsecフィールドに1秒以上のナノ秒を持つことができますか?

//milli is an int that can be any number (within reason) 
struct timespec ts; 
clock_gettime(CLOCK_REALTIME, &ts); 
ts.tv_nesc += (milli*1000000); 

または私はそれを分割し、任意の全体秒は最初があるかどうかを調べる、tv_secフィールドにそれらを追加し、tv_nsecに残りを追加する必要がありますか?

tv_nsecフィールドは、1秒間に1ナノ秒以上保存できますか?

答えて

12

これは、あなたがそれをどうしようとしているかによってまったく異なります。

struct timespectv_nsecのメンバーは、タイプlongです。範囲LONG_MINからLONG_MAXまでの任意の値に設定できます。 LONG_MAX(少なくとも2 -1)を超える計算を実行すると、問題が発生する可能性があります(定義されていない動作はとなる可能性があります。は値の折り返しとして表示されます)。

0より小さい値または10億以上の値に設定するかどうかは、その操作に応じて問題が発生します。それを印刷したい、あるいは何らかの計算をしたいだけなら、有効なlongの値は大丈夫ですが、標準化した方が保存された値はおそらくもっと有用でしょう。

clock_gettime()は、常にtv_nsecという値を0..999999999の範囲で指定する必要があります。

POSIXが失敗するclock_settime()clock_nanosleep()、及びnanosleep()機能を必要とした場合に、EINVALerrno設定「TP引数が1000百万ゼロ未満または以上のナノ秒の値を指定しました。」

参考文献:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_settime.html http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_nanosleep.html http://pubs.opengroup.org/onlinepubs/9699919799/functions/nanosleep.html

+0

+1。しかし、それを説明する価値はあります。完全にPOSIX/Cポータブルにしたい場合は、追加などの前にオーバーフローをチェックする必要がありますが、これは楽しいことではありません。すべての実用的なPOSIXプラットフォームで作業したいだけで、非正規化されたtimespecや1G以上のnanosを追加していない場合は、 'long'がどのように動作するかについての通常の仮定をすることができます。 linuxだけを気にしているなら 'timespec_add_safe' /' timespec_add'や 'set_normalized_timespec'を使うことができます。 – abarnert

+0

@Keith Thompson私はposix stdへのあなたのリンクに従ってきました。あなたが話しているPOSIX保証がclock_settime()のために定義されているように見えます。 msgstr "clock_settime()関数は次の場合に失敗します:"、。それとも私は何かが恋しい?実際に私はそのような保護者に興味があるので! :-) –

+0

@yvesBaumes:私はちょうど私の答えを少しきれいにしました。あなたは何の保証をしていますか? –

1

tv_nsecフィールドは、限定(2つの有効なTIMESPECナノ秒の値を追加するのに常に十分なので、= 1999999998 999999999 + 999999999)ナノ秒のオーバーフロー量を許容します。ただし、任意のオーバーフローが保証されているわけではありません.32ビットのlongの実装では、2秒間のわずかな秒数で2.147483647秒になります。だから誰かが2500ミリ秒(2.5秒)を追加するように指示した場合、それはオーバーフローします。

編集の追加:Keith Thompson氏は、あるtimespecを別のtimespecに追加した後に再正規化する必要があることに留意してください。

関連する問題