为什么这些时间戳与Perl Time :: HiRes无关?

时间:2016-09-22 17:45:34

标签: perl unix timestamp ext4

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

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

  1. 获取Time::HiRes::time
  2. 的时间戳
  3. 创建一个新文件,并使用Time::HiRes::stat
  4. 获取修改时间
  5. 获取Time::HiRes::time
  6. 的时间戳

    我希望订购时间戳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";
        }
    }
    

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

    enter image description here

    有什么可以解释这种行为?

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

    enter image description here

1 个答案:

答案 0 :(得分:5)

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

  

作为stat或lstat但是   以亚秒级分辨率访问/修改/更改文件时间戳,   如果操作系统和文件系统都支持这样的话   时间戳。要覆盖标准stat():

use Time::HiRes qw(stat);
     

测试&amp; Time :: HiRes :: d_hires_stat的值以确定操作系统是否正常   支持亚秒文件时间戳:大于零的值表示   是。遗憾的是,没有简单的方法可以找出是否有   filesystem支持这样的时间戳。 UNIX文件系统经常这样做; NTFS   做; FAT没有(FAT时间戳粒度两个秒)。

     

零   返回值&amp; Time :: HiRes :: d_hires_stat意味着   Time :: HiRes :: stat是CORE :: stat()的无操作直通(和   同样对于lstat),因此时间戳将保持整数。   如果文件系统不在亚秒级,则会发生同样的事情   时间戳,即使&amp; Time :: HiRes :: d_hires_stat非零。

     

任何一个   案例不要指望纳秒分辨率,甚至是微秒   解析度。另请注意,修改/访问时间戳可能有   不同的分辨率,并且它们不需要同步,例如如果   操作是

write
stat # t1
read
stat # t2
     

来自t2的访问时间戳不必大于修改   来自t1的时间戳:它可能相等或更少