gpt4 book ai didi

c - 使用 clock_gettime 和 struct stat.mtim 的时序偏差

转载 作者:太空宇宙 更新时间:2023-11-03 23:44:27 25 4
gpt4 key购买 nike

下面的C程序首先使用clock_gettime()获取时间,然后创建一个文件并读出它的修改时间。至少在我的系统上,文件 mtime 是一个比 clock_gettime() 的结果更旧的时间戳。我的问题是如何解释这一点,是否有一个标准(例如 POSIX)指定两者必须按顺序排列?

/* Compile as C11 */
#define _POSIX_C_SOURCE 200809L

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
struct timespec buf_start;

int r= clock_gettime(CLOCK_REALTIME, &buf_start);
if (r != 0) {
perror("clock_gettime");
exit(1);
}

FILE *file= fopen("A", "w");
if (file == NULL) {
perror("A");
exit(1);
}
r= fputs("aaa\n", file);
if (r == EOF) {
perror("A");
exit(1);
}
r= fclose(file);
if (r != 0) {
perror("A");
exit(1);
}

struct stat stat_file;

r= stat("A", &stat_file);
if (r != 0) {
perror("A");
exit(1);
}

r= printf("%ld.%9ld\n%ld.%9ld\n",
buf_start.tv_sec, buf_start.tv_nsec,
stat_file.st_mtim.tv_sec, stat_file.st_mtim.tv_nsec);
if (r < 0) {
perror("printf");
exit(1);
}

exit(0);
}

在我的系统 (Ubuntu 14.04) 上,使用 gcc 4.8.4 和 ext4 文件系统,输出是:

1463778756.834469527
1463778756.832709123

即,程序的启动时间报告为文件修改时间之后 2 毫秒。

编辑:使用 CLOCK_REALTIME_COARSE,两个结果时间戳完全相等,精确到纳秒。

编辑:clock_getres(CLOCK_REALTIME, ...) 返回的分辨率是一纳秒。

编辑:添加了文件系统信息。

最佳答案

根据用户 Nos 的研究和提供的链接,这里是问题的答案:(免责声明:我是最初的提问者)

在 Linux 上,ext4 中的时间戳以纳秒精度保存,但时间戳本身被缓存。 Linux 内核定期确定纳秒精度时间(这是一项昂贵的操作)并将其保存在全局变量中。在该变量的下一次更新之前,写入磁盘(或某些其他数据结构)的所有时间戳都设置为此值,而不是当前时间。因此,ext4 文件系统中文件的时间戳有点太旧了。该错误大约为几毫秒。

另一方面,调用 clock_gettime() 获取当前时间返回(计算成本高)高精度当前时间。

就 POSIX 等标准而言,我找不到任何关于问题中给出的程序的声明。我认为此类问题将被视为任何“实时”行为的一部分,而不是通常操作系统界面的一部分。

实际上,可以使用 CLOCK_REALTIME_COARSE 来获得“文件系统兼容”的时间戳。然而,这是特定于 Linux 的,它的工作原理也是基于对 ext4 内部工作的了解,并且将来可能会更改,恕不另行通知。

对于 POSIX 标准,我希望有一个标志 CLOCK_FILESYSTEM 或类似的标志来保证像问题中给出的程序那样的程序按预期工作。这也将允许 clock_getres(CLOCK_FILESYSTEM) 返回该时钟的实际粒度。

关于c - 使用 clock_gettime 和 struct stat.mtim 的时序偏差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37355989/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com