以微秒为单位获取C的时间戳?

时间:2011-04-29 14:03:22

标签: c time

如何在C中获得微秒时间戳?

我正在尝试:

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

但是这会返回一些无意义的值,如果我得到两个时间戳,第二个可以比第一个更小或更大(第二个应该总是更大)。是否可以将 gettimeofday 返回的魔术整数转换为可以实际使用的正常数字?

8 个答案:

答案 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)

来自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

答案 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()

参考:

  1. 我在上面链接到的 cppreference.com 文档来源。
  2. Getting an accurate execution time in C++ (micro seconds)

另见:

  1. 我的 3 组时间戳函数(相互交叉链接):
    1. 对于 C 时间戳,请在此处查看我的回答:This answer here by @Ciro Santilli新疆棉花
    2. 对于 C++ 高分辨率时间戳,请在此处查看我的回答:Get a timestamp in C in microseconds?
    3. 对于 Python 高分辨率时间戳,请在此处查看我的回答:Getting an accurate execution time in C++ (micro seconds)