如何在C中获得微秒时间戳?
我正在尝试:
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_usec;
但是这会返回一些无意义的值,如果我得到两个时间戳,第二个可以比第一个更小或更大(第二个应该总是更大)。是否可以将 gettimeofday 返回的魔术整数转换为可以实际使用的正常数字?
答案 0 :(得分:46)
您还需要在几秒钟内添加:
unsigned long time_in_micros = 1000000 * tv.tv_sec + tv.tv_usec;
请注意,这只会持续大约2 32 / 10 6 = ~4295秒,或大约71分钟(在典型的32位系统上)。
答案 1 :(得分:18)
获得微秒时间戳有两种选择。第一个(也是最好的)选择是直接使用timeval
类型:
struct timeval GetTimeStamp() {
struct timeval tv;
gettimeofday(&tv,NULL);
return tv;
}
第二个,对我来说不太理想,选择是从timeval
构建一个uint64_t:
uint64_t GetTimeStamp() {
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_sec*(uint64_t)1000000+tv.tv_usec;
}
答案 2 :(得分:8)
struct timeval包含两个组件,第二个和微秒。具有微秒精度的时间戳表示为自tv_sec字段中存储的纪元以及tv_usec中的小数微秒以来的秒数。因此,你不能只是忽略tv_sec并期待合理的结果。
如果你使用Linux或* BSD,你可以使用timersub()来减去两个struct timeval值,这可能是你想要的。
答案 3 :(得分:2)
但是这会返回一些无意义的值 如果我得到两个时间戳,那么 第二个可以更小或更大 比第一个(第二个应该 总是更大。)
是什么让你这么想?价值可能还可以。它与秒和分钟的情况相同 - 当您以分钟和秒为单位测量时间时,当秒数达到60时,秒数就会翻到零。
要将返回值转换为“线性”数字,您可以将秒数相乘并添加微秒。但如果我算一算,一年大约是1e6 * 60 * 60 * 24 *360μsec,这意味着你需要超过32位才能存储结果:
$ perl -E '$_=1e6*60*60*24*360; say int log($_)/log(2)'
44
这可能是将原始返回值分成两部分的原因之一。
答案 4 :(得分:2)
timespec_get 返回最多纳秒,四舍五入到实现的分辨率。
#include <time.h>
struct timespec ts;
timespec_get(&ts, TIME_UTC);
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
答案 5 :(得分:0)
首先我们需要知道微秒的范围,即000_000到999_999(1000000微秒等于1秒)。 tv.tv_usec将返回0到999999之间的值而不是 000000到999999 ,所以当使用它时,我们可能会得到2.1秒而不是2.000001秒,因为只讨论tv_usec 000001基本上是1。 如果你插入
会更好if(tv.tv_usec<10)
{
printf("00000");
}
else if(tv.tv_usec<100&&tv.tv_usec>9)// i.e. 2digits
{
printf("0000");
}
依旧......
答案 6 :(得分:0)
使用无符号长整数(即64位单位)来表示系统时间:
typedef unsigned long long u64;
u64 u64useconds;
struct timeval tv;
gettimeofday(&tv,NULL);
u64useconds = (1000000*tv.tv_sec) + tv.tv_usec;
答案 7 :(得分:0)
CMD [ "/root/keep-alive.sh" ]
以毫秒 (ms)、millis()
以微秒 (us) 和 micros()
} 获取以纳秒 (ns) 为单位的简单时间戳这适用于 C11。见documentation for timespec_get()
here。
它也适用于 C++17。见documentation for std::timespec_get()
here。
但是,对于 C++11 及更高版本,我更喜欢使用不同的方法,我可以指定分辨率和时钟类型,正如我在此处的回答中所演示的:{{ 3}}。
另一方面,C11 nanos()
解决方案受到更多限制,因为您无法指定时钟分辨率或单调性(“单调”时钟被定义为仅向前计数并且可以永远不要向后走或向后跳--例如:用于时间更正)。在测量时差时,需要单调时钟以确保您永远不会将时钟校正跳跃计入“测量”时间的一部分。
以下函数返回的时间戳值的分辨率,因此,由于我们无法指定要使用的时钟,可能取决于您的硬件架构、操作系统 和 编译器。
无论如何,这是我在 C11 中用于简单时间戳和代码速度分析的 timespec_get()
、millis()
和 micros()
函数:
nanos()