在 Windows 上我可以调用:
_time32(__time32_t); // to get 32-bit time_t
_time64(__time64_t); // to get 64-bit time_t
(32 位和 64 位程序)
有什么办法在Linux中做到这一点(用GCC编译)?
上面很多答案都说这是不可能的,但这是完全错误的。当时“这是不可能的”,但人们多年来一直在“谈论修复它”。最后,32 位平台上的 64 位时间支持被引入到 Linux 5.1 内核,并添加了新的 *time64
系统调用。查看此表
,您可以看到这些系统调用仅在 32 位平台上可用。现在,如果您正在为 32 位系统编写代码,您可以直接调用
clock_gettime64
(通过内联汇编或带有 syscall()
的 C)来获取当前时间
但是之后你就完全靠自己了。如果您想要完整的userspace支持,您必须使用Linux 5.6或更高版本以及musl 1.2+或glibc 2.32+。只需重建你的代码,你的
time_t
就会变成64位长
所有用户空间都必须使用 64 位time_t
进行编译,即将推出的 musl-1.2 和 glibc-2.32 版本以及 linux-5.6 或更高版本中安装的内核头文件将支持该版本。
- 系统调用来代替现有的系统调用。这会影响
直接使用系统调用接口的应用程序需要移植以使用linux-5.1中添加的
time64
futex()
和
的大多数用户以及拥有自己的运行时环境但不基于 libc 的编程语言。 https://lkml.org/lkml/2020/1/29/355?anz=webseccomp()
不幸的是,正如 Debian 在过渡时所说的那样
你可能仍然需要在各种情况下构建自己的库
glibc 2.34 支持现有的 32 位 ABI/API 和新的 64 位 ABI/API。但是,它不提供强制使用新 API/ABI 的开关 - 每个构建/包都明确选择使用 64 位 API/ABI(通过设置 _TIME_BITS=64
1030159已实现
选项作为一致的 Debian 机制。DEB_BUILD_OPTIONS=abi=+time64
欲了解更多信息
接近2038年内核终局游戏
time()
time32()
或
time64()
。 搜索了一段时间,发现不是libc的错,罪魁祸首其实是内核。
为了让 libc 获取当前时间,需要执行系统调用:(
Source
)(Source)
SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
time_t i = get_seconds();
// ...
return i;
}
函数
get_seconds()
返回一个
unsigned long
,如下所示:
(Source
)
unsigned long get_seconds(void)
{
struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;
}
并且 timekeeper.xtime_sec
实际上是 64 位:(
Source
)
struct timekeeper {
// ...
/* Current CLOCK_REALTIME time in seconds */
u64 xtime_sec;
// ...
}
现在,如果您了解 C,您就会知道 unsigned long
的大小实际上取决于实现。在我这里的64位机器上,它是64位的;但在我这里的 32 位机器上,它是 32 位的。在某些 32 位实现上,它“可能”可能是 64 位,但不能保证。
另一方面,
u64
始终是64位,因此从根本上来说,内核以64位类型跟踪时间。为什么它会继续将其返回为 unsigned long
(不保证为 64 位长),我无法理解。
最终,即使 libc 会强制
time_t
保存 64 位值,也不会改变任何事情。您可以将您的应用程序深深地绑定到内核中,但我认为这根本不值得。
标准库中未包含
time64()/time32()
函数。
time32_t/time64_t
定义。
time_t
定义为
time.h
为 typedef __time_t time_t
;
经过一长串的重新定义,您会发现
__time_t
在 32 位机器上被定义为 32 位,在 64 位机器上被定义为 64 位。使用此库:
https://github.com/evalEmpire/y2038
如果你真的需要这个,为什么不自己动手呢?
typedef int32_t my_time32; typedef int64_t my_time64; my_time32 get_mytime32() { if (sizeof(time_t) == sizeof(my_time32)) return time(NULL); else { /* Check for overflow etc. here... */ return (my_time32)(time(NULL)); } }
get_mytime64()
。
如果您不关心溢出问题,由于 C 的隐式数字转换,一个简单的
return time(NULL);
对这两个函数都适用。