web-dev-qa-db-ja.com

マイクロ秒単位でCのタイムスタンプを取得しますか?

Cでマイクロ秒のタイムスタンプを取得するにはどうすればよいですか?

私がやろうとしている:

struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_usec;

しかし、これはいくつかのナンセンスな値を返します。2つのタイムスタンプを取得した場合、2番目のタイムスタンプは最初のタイムスタンプよりも小さいか大きい場合があります(2番目のタイムスタンプはalwaysより大きい必要があります)。 gettimeofdayによって返されるマジック整数を、実際に使用できる通常の数値に変換することは可能でしょうか?

39
Kristina Brooks

数秒で追加する必要もあります。

unsigned long time_in_micros = 1000000 * tv.tv_sec + tv.tv_usec;

これは約2分間しか持続しないことに注意してください32/ 106 =〜4295秒、または約71分(ただし、一般的な32ビットシステム)。

47
unwind

マイクロ秒のタイムスタンプを取得するには、2つの選択肢があります。最初の(そして最良の)選択は、timeval型を直接使用することです:

struct timeval GetTimeStamp() {
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return tv;
}

2番目の、そして私にとってあまり望ましくない選択肢は、timevalからuint64_tを構築することです。

uint64_t GetTimeStamp() {
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return tv.tv_sec*(uint64_t)1000000+tv.tv_usec;
}
18
Robᵩ

struct timevalには、2番目とマイクロ秒の2つのコンポーネントが含まれます。マイクロ秒精度のタイムスタンプは、エポックがtv_secフィールドに格納されてからの秒数、およびtv_usecの小数マイクロ秒として表されます。したがって、単にtv_secを無視して、適切な結果を期待することはできません。

Linuxまたは* BSDを使用している場合、timersub()を使用して2つのstruct timeval値を減算できます。

8
janneb

C11からのtimespec_getは、実装の解像度に丸められた最大ナノ秒を返します。

#include <time.h>
struct timespec ts;
timespec_get(&ts, TIME_UTC);
struct timespec {
    time_t   tv_sec;        /* seconds */
    long     tv_nsec;       /* nanoseconds */
};

詳細はこちら: https://stackoverflow.com/a/36095407/895245

しかし、これはいくつかのナンセンス値を返します。2つのタイムスタンプを取得した場合、2番目のタイムスタンプは最初のタイムスタンプよりも小さくまたは大きくなります(2番目のタイムスタンプは常に大きくする必要があります)。

何があなたをそう思わせたのですか?値はおそらく大丈夫です。秒や分と同じ状況です。時間を分と秒で測定すると、秒が60に達するとゼロにロールオーバーします。

返された値を「線形」数に変換するには、秒数を掛けてマイクロ秒を追加します。しかし、正しくカウントすると、1年は約1e6 * 60 * 60 * 24 * 360µμsecであり、結果を保存するには32ビット以上が必要になります。

$ Perl -E '$_=1e6*60*60*24*360; say int log($_)/log(2)'
44

これがおそらく、元の戻り値を2つに分割する理由の1つです。

2
zoul

システム時間を表すために、符号なしlong long(つまり64ビット単位)を使用します。

typedef unsigned long long u64;

u64 u64useconds;
struct timeval tv;

gettimeofday(&tv,NULL);
u64useconds = (1000000*tv.tv_sec) + tv.tv_usec;
0
user6269400

まず、マイクロ秒の範囲、つまり000_000から999_999(1000000マイクロ秒は1秒に等しい)を知る必要があります。 tv.tv_usecは、0から999999の値を返します0000から999999ではないため、秒で使用すると、2.000001秒ではなく2.1秒になる可能性があります。あなたが挿入します

if(tv.tv_usec<10)
{
 printf("00000");
} 
else if(tv.tv_usec<100&&tv.tv_usec>9)// i.e. 2digits
{
 printf("0000");
}

等々...

0
Osaid