【问题标题】:Is it a bug in Linux time() function or Linux OS calls?它是 Linux time() 函数或 Linux 操作系统调用中的错误吗?
【发布时间】:2010-03-10 06:46:58
【问题描述】:

我写了一个小程序,它以 1 分钟的间隔创建文件。但是 ls 命令显示的文件创建和最后写入时间与文件的最后修改时间相差 1 秒。代码和输出如下所示。请让我知道错误可能在哪里?

root@new:/home/srinivas# cat b.c
#include <time.h>
#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
int main ()
{
    int fd;
    int i=0;
    time_t initial_time = time(NULL);
    time_t interval = 60;
    time_t curr_time = time(NULL);

    fd=open ("test1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    write(fd,"abcd1",5);
    while(1)
    {
        curr_time = time(NULL);
        if(curr_time >= initial_time)
        {
            if(i==0)
            {
                close(fd);
                printf("\ntime before test2.txt fileopen= %d\n", time(NULL));
                fd=open ("test2.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
                write(fd,"abcd2",5);
                printf("time after test2.txt filewrite= %d\n", time(NULL));
                system("ls -l --time-style=+%s test2.txt");
                initial_time += interval;
                i=1;
            }
            else
            {
                close(fd);
                printf("\ntime before test1.txt fileopen= %d\n", time(NULL));
                fd=open ("test1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
                write(fd,"abcd1",5);
                printf("time after test1.txt filewrite= %d\n", time(NULL));
                system("ls -l --time-style=+%s test1.txt");
                initial_time += interval;
                i=0;
            }
        }
        usleep(1000);
    }
    return 0;
}
root@new:/home/srinivas# gcc b.c
root@new:/home/srinivas# ./a.out

time before test2.txt fileopen= 1268203133
time after test2.txt filewrite= 1268203133
-rw-r--r-- 1 root root 5 1268203133 test2.txt

time before test1.txt fileopen= 1268203193
time after test1.txt filewrite= 1268203193
-rw-r--r-- 1 root root 5 1268203192 test1.txt

time before test2.txt fileopen= 1268203253
time after test2.txt filewrite= 1268203253
-rw-r--r-- 1 root root 5 1268203252 test2.txt

time before test1.txt fileopen= 1268203313
time after test1.txt filewrite= 1268203313
-rw-r--r-- 1 root root 5 1268203312 test1.txt

time before test2.txt fileopen= 1268203373
time after test2.txt filewrite= 1268203373
-rw-r--r-- 1 root root 5 1268203372 test2.txt

root@new:/home/srinivas# ls -ltr --time-style=+%s
total 40
-rwxrwxrwx  1 root     root      1095 1268202457 b.c
-rwxr-xr-x  1 root     root     10300 1268202459 a.out
-rw-r--r--  1 root     root         5 1268203312 test1.txt
-rw-r--r--  1 root     root         5 1268203372 test2.txt
root@new:/home/srinivas#

感谢和问候,

斯里尼瓦

【问题讨论】:

  • 这里运行良好,但您看到的确实出乎意料...您的主目录是否使用了一些“奇怪”的文件系统,如 NFS,或任何特殊的挂载选项?
  • @Martin - 我能够在本地安装的文件系统上重现它。很奇怪……
  • @Martin - 我的 /home 是 ext3 格式的。不是挂载的分区。

标签: linux time ls


【解决方案1】:

首先,你的代码有问题。

  • 删除循环前的open()write(),它们什么都不做。
  • write() 调用之后移动两个close() 调用。

这将确保在您使用 ls 查看其修改时间之前写入数据并关闭文件。否则,write() 和 close() 之间会有 1 秒的延迟。由于您只写入 5 个字节,因此它将被缓冲。所以,当你在 write() 调用之后检查时间时,你不能保证数据已经被写入,所以文件可能没有被修改,这可能会搞砸你的结果。

其次,您不能假设有 1 秒的延迟,因为 time()ls 报告了 1 秒的差异。因为一秒是你的最小单位,你应该期待四舍五入的差异。而且由于您使用两种不同的方法来获取自 Epoch 以来的秒数,它们可能使用不同的舍入规则,这很容易导致 1 秒的差异。如果我们将存储修改时间的文件系统添加到该文件系统中,您实际上有三个不同的参与者可能会影响您的结果。

此外,如果您正确查看结果,您会看到它的time() 表示比ls 晚一秒。所以,你根本没有延迟,你会回到过去!四舍五入的差异是最可能的原因。

因此,Linux time() 函数或 Linux 操作系统调用中没有错误。

【讨论】:

  • 其实这正是我原来需要的程序/功能的复制品。因此,尽管移动 open()、write() 函数会隐藏问题,但我一直在寻找由于我的原始代码而暴露的问题的答案。
  • @Srinivas 我不确定你在说什么......我不希望你移动 open() 和 write(),我希望你删除它们。这将允许在您的 write() 调用之后进行 close() 调用,因此它们之间没有延迟。否则,write() 和 close() 之间会有 1 秒的延迟。由于您只写入 5 个字节,因此它将被缓冲。所以,当你在 write() 调用之后检查时间时,你不能保证数据已经被写入,所以文件可能没有被修改,这可能会搞砸你的结果。
【解决方案2】:
【解决方案3】:
  • 写入文件需要一些时间。
  • 调用 time() 函数需要一些时间
  • time() 函数的逻辑执行需要一些时间。

所有这些都会导致 1 秒的延迟......这根本不是错误!

【讨论】:

    猜你喜欢
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    相关资源
    最近更新 更多