17

在 Windows 上,我可以调用:

_time32(__time32_t); // to get 32-bit time_t
_time64(__time64_t); // to get 64-bit time_t

(在 32 位和 64 位程序中)

在 Linux 中有什么方法可以做到这一点(用 GCC 编译)?

4

5 回答 5

14

显然,不,这是不可能的。对于初学者来说,Linux 中只有一个time()函数,notime32()time64().

搜索了一会,发现不是libc的错,而罪魁祸首其实是内核。

为了让 libc 获取当前时间,它需要对其执行系统调用:(Source

time_t time (t) time_t *t;
{
    // ...
    INTERNAL_SYSCALL_DECL (err);
    time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
    // ...
    return res;
}

系统调用定义为: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 位的:(来源

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 位值,它也不会改变任何事情。

您可以将您的应用程序深深地绑定到内核中,但我认为这甚至不值得。

于 2013-01-16T17:06:53.383 回答
9

上面的许多答案都说这是不可能的,但这完全不正确。当时这不可能的,但人们多年来一直在谈论修复它最后,Linux 5.1 内核引入了32 位平台上的 64 位时间支持,并添加了新的*time64系统调用。查看此表,您可以看到这些系统调用仅在 32 位平台上可用。现在,如果您正在为 32 位系统编写代码,您可以clock_gettime64直接调用(从内联汇编或 C with syscall())来获取当前时间

然而,在那之后你就完全靠自己了。如果您想要完整的用户空间支持,您必须使用 Linux 5.6 或更高版本以及 musl 1.2+ 或 glibc 2.32+。只需重建您的代码,您的代码time_t将变为 64 位长

  • 所有用户空间都必须使用 64 位编译,time_t即将到来的 musl-1.2 和 glibc-2.32 版本以及已安装的 linux-5.6 或更高版本的内核头文件将支持该版本。

  • 直接使用系统调用接口的应用程序需要移植以使用time64linux-5.1 中添加的系统调用来代替现有的系统调用。这会影响大多数用户futex()以及seccomp()拥有自己的运行时环境而不基于 libc 的编程语言。

https://lkml.org/lkml/2020/1/29/355?anz=web

了解更多信息

于 2020-03-16T16:08:24.757 回答
7

标准库中不包含任何time64()/time32()功能。

标准头文件中不考虑任何time32_t/time64_t定义。

time_t定义time.htypedef __time_t time_t;

经过一长串的重新定义,您会发现__time_t在 32 位机器上定义为 32 位,在 64 位机器上定义为 64 位。

于 2013-01-16T16:01:37.670 回答
1

使用这个库:https ://github.com/evalEmpire/y2038

该项目的目标是为 POSIX time.h 提供一个替代品,它可以在具有 32 位 time_t 的机器上工作,但不会受到 2038 错误的影响。这将允许 C 程序员在 2038 年安全,而无需将他们的软件重写为新接口。它在仍然使用系统时区数据库的同时执行此操作。

于 2018-10-26T14:05:19.800 回答
-2

如果你真的需要这个,为什么不自己动手呢?

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().

如果您不关心溢出,return time(NULL);由于 C 的隐式数字转换,一个简单的函数对这两个函数都有效。

于 2013-01-16T17:15:34.733 回答