perl - 为什么这些时间戳与 Perl Time::HiRes 不一致?

标签 perl unix timestamp ext4

我看到 Perl 的 Time::HiRes 报告的时间戳出现了一些奇怪的行为。模块。

我有一个获取三个时间戳的脚本:

  • 使用 Time::HiRes::time 获取时间戳
  • 创建一个新文件,并使用 Time::HiRes::stat 获取其修改时间
  • 使用 Time::HiRes::time 获取时间戳

  • 我希望时间戳被订购 1 < 2 < 3 ,但情况并非总是如此;经常(但不总是)stat 报告的时间2. 在时间戳之前 1..

    我在一个 Ext4 文件系统上。这是一个实验:
    use Time::HiRes qw/ time stat /;
    
    while( 1 ){
        # t0
        my $t0 = time;
    
        # Create a file
        my $f = '/tmp/dummy.test';
        open(my $fh, '>', $f) || die;
        print $fh "hi\n";
        close($fh) || die;
    
        # FS: file modification time, according to the filestystem
        my $fs = (stat($f))[9];
    
        # t1
        my $t1 = time;
    
        ## Report how the timestamps relate to each other
        # A. All good
        if( $t0 < $fs && $fs < $t1 ){
           print "$t1,0\n";
        }
        # B. FS before t0
        elsif( $t0 > $fs && $fs < $t1 ){
           print "$t1,1\n";
        }
        # C. FS after t1
        elsif( $t0 < $fs && $fs > $t1 ){
           print "$t1,2\n";
        }
        # D. this should never happen (t0 and t1 probably can't flip)
        elsif( $t0 > $fs && $fs > $t1 ){
           print "$t1,3\n";
        }
    }
    

    这是让上述循环运行几秒钟的结果。其中底部的蓝点是“正确”行为的事件。通常情况下,我得到条件 B ,其中修改时间来自stat在第一个时间戳之前。

    enter image description here

    什么可以解释这种行为?

    更新:这是第 2000 次迭代的时间戳滞后图:

    enter image description here

    最佳答案

    这可能是因为文档 here 中提到的两个时间戳的精度不同。 :

    As stat or lstat but with the access/modify/change file timestamps in subsecond resolution, if the operating system and the filesystem both support such timestamps. To override the standard stat():

    use Time::HiRes qw(stat);
    

    Test for the value of &Time::HiRes::d_hires_stat to find out whether the operating system supports subsecond file timestamps: a value larger than zero means yes. There are unfortunately no easy ways to find out whether the filesystem supports such timestamps. UNIX filesystems often do; NTFS does; FAT doesn't (FAT timestamp granularity is two seconds).

    A zero return value of &Time::HiRes::d_hires_stat means that Time::HiRes::stat is a no-op passthrough for CORE::stat() (and likewise for lstat), and therefore the timestamps will stay integers. The same thing will happen if the filesystem does not do subsecond timestamps, even if the &Time::HiRes::d_hires_stat is non-zero.

    In any case do not expect nanosecond resolution, or even a microsecond resolution. Also note that the modify/access timestamps might have different resolutions, and that they need not be synchronized, e.g. if the operations are

    write
    stat # t1
    read
    stat # t2
    

    the access time stamp from t2 need not be greater-than the modify time stamp from t1: it may be equal or less.

    关于perl - 为什么这些时间戳与 Perl Time::HiRes 不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39645621/

    相关文章:

    java - 如何将对象与 Date 变量进行比较(Hibernate)? java.util.Date 与 java.sql.Timestamp

    linux - 如何在 javacc 中更新和打印 'Rational' token ?

    mysql - SQL 查询在特定日期不起作用

    perl - 在 XS 中,如何从变量名中获取变量地址?

    perl - Perl 中的嵌套 foreach 循环仅循环一次

    c - 多个进程中的静态变量(信号)

    c - 是否有充分的理由编写我自己的 daemonize 函数而不是使用 daemon(3)?

    php - CodeIgniter - MySql 时间戳/日期时间在插入时不断给我零

    perl - 使用 Moose 进行对象组合的最佳方法是什么?

    regex - 在 Perl 正则表达式中转义特殊字符