调用 clock_gettime() 时,返回的 tv_nsec 字段实际上可能超过一秒吗?
When invoking clock_gettime() may the returned tv_nsec field actually exceed a second?
当您调用 clock_gettime()
时,它 returns 一个 timespec 结构。
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
我在手册页中找不到 tv_nsec 不会超过一秒的保证。担保是否真实存在?它可能依赖于 linux 的库 (glibc?) 实现吗?
关键思想是:我是否需要 'normalize' 来自 clock_gettime()
函数的任何结果?
我相当确定答案总是"no"。
clock_gettime 不会 return 且 tv_nsec >= 10e9。 clock_settime() 和 clock_nanosleep() 都对他们的输入施加了这个限制,所以我一直认为 clock_gettime 与此一致。
同样在 Linux + glibc 上,如果你足够深入地研究 glibc,你会看到这样的代码:
摘自glibc/nptl/pthread_clock_gettime.c:
/* Compute the seconds. */
tp->tv_sec = tsc / freq;
/* And the nanoseconds. This computation should be stable until
we get machines with about 16GHz frequency. */
tp->tv_nsec = ((tsc % freq) * 1000000000ull) / freq;
这也发生在 glibc/sysdeps/unix/clock_gettime.c.
但是你是对的,手册页没有说。至少我的 Linux 发行版或 opengroup.org 上没有。因此,实施在技术上可能会发生变化 w/o 警告。
如果您正在为 Linux + glibc 写作,我会说您很安全。您可以自己检查备用开源 libc 库,例如Android 的仿生,或按比例缩小的 newlib。
如果您的目标是其他闭源 POSIX 系统,您或您的客户在支付支持费用方面存在问题,因此如果没有记录,请询问供应商。
如果试图尽可能便携并且感觉偏执,请用这样的 "normalizing" 函数包装 clock_gettime:
int my_gettime( struct timespec * ts )
{
int ret;
if( 0 == (ret = clock_gettime(SOME_CLOCK, ts))
{
while (tv_nsec >= 1000000000 )
{
ts->tv_nsec -= 1000000000;
ts->tv_sec += 1;
}
}
return ret;
}
不,您不需要对结果进行标准化。您可以相信纳秒字段在 0 到 999999999 之间(含)。
clock_gettime()
的 POSIX 规范明确指出,如果 tv_nsec < 0 || tv_nsec >= 1000000000
.
,clock_settime()
将失败并显示 EINVAL
标准的学究们可能会争辩,但简单的对称本身就告诉我们,我们可以期待 clock_gettime()
的结果相同。从技术上讲,10e9 ns 是一秒,并且由于标准始终使用术语 "seconds and nanoseconds",因此合乎逻辑的结论是纳秒字段应该被归一化。此外,如果 clock_gettime()
要 return 结果纳秒字段超出范围,许多程序将以有趣和迷人的方式出现故障。
The tv_nsec member is only valid if greater than or equal to zero, and
less than the number of nanoseconds in a second (1000 million). The
time interval described by this structure is (tv_sec * 10'-.4m'9'.4m'
+ tv_nsec) nanoseconds.
所以按照opengroup的说法,官方说肯定是1秒以内。
当您调用 clock_gettime()
时,它 returns 一个 timespec 结构。
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
我在手册页中找不到 tv_nsec 不会超过一秒的保证。担保是否真实存在?它可能依赖于 linux 的库 (glibc?) 实现吗?
关键思想是:我是否需要 'normalize' 来自 clock_gettime()
函数的任何结果?
我相当确定答案总是"no"。
clock_gettime 不会 return 且 tv_nsec >= 10e9。 clock_settime() 和 clock_nanosleep() 都对他们的输入施加了这个限制,所以我一直认为 clock_gettime 与此一致。
同样在 Linux + glibc 上,如果你足够深入地研究 glibc,你会看到这样的代码:
摘自glibc/nptl/pthread_clock_gettime.c:
/* Compute the seconds. */
tp->tv_sec = tsc / freq;
/* And the nanoseconds. This computation should be stable until
we get machines with about 16GHz frequency. */
tp->tv_nsec = ((tsc % freq) * 1000000000ull) / freq;
这也发生在 glibc/sysdeps/unix/clock_gettime.c.
但是你是对的,手册页没有说。至少我的 Linux 发行版或 opengroup.org 上没有。因此,实施在技术上可能会发生变化 w/o 警告。
如果您正在为 Linux + glibc 写作,我会说您很安全。您可以自己检查备用开源 libc 库,例如Android 的仿生,或按比例缩小的 newlib。
如果您的目标是其他闭源 POSIX 系统,您或您的客户在支付支持费用方面存在问题,因此如果没有记录,请询问供应商。
如果试图尽可能便携并且感觉偏执,请用这样的 "normalizing" 函数包装 clock_gettime:
int my_gettime( struct timespec * ts )
{
int ret;
if( 0 == (ret = clock_gettime(SOME_CLOCK, ts))
{
while (tv_nsec >= 1000000000 )
{
ts->tv_nsec -= 1000000000;
ts->tv_sec += 1;
}
}
return ret;
}
不,您不需要对结果进行标准化。您可以相信纳秒字段在 0 到 999999999 之间(含)。
clock_gettime()
的 POSIX 规范明确指出,如果 tv_nsec < 0 || tv_nsec >= 1000000000
.
clock_settime()
将失败并显示 EINVAL
标准的学究们可能会争辩,但简单的对称本身就告诉我们,我们可以期待 clock_gettime()
的结果相同。从技术上讲,10e9 ns 是一秒,并且由于标准始终使用术语 "seconds and nanoseconds",因此合乎逻辑的结论是纳秒字段应该被归一化。此外,如果 clock_gettime()
要 return 结果纳秒字段超出范围,许多程序将以有趣和迷人的方式出现故障。
The tv_nsec member is only valid if greater than or equal to zero, and less than the number of nanoseconds in a second (1000 million). The time interval described by this structure is (tv_sec * 10'-.4m'9'.4m' + tv_nsec) nanoseconds.
所以按照opengroup的说法,官方说肯定是1秒以内。