我在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";
}
}
以下是让上述循环运行几秒钟的结果。底部的蓝点是&#34;正确&#34;的事件。行为。通常情况下,我得到条件B
,其中stat
的修改时间是之前第一个时间戳。
有什么可以解释这种行为?
更新:这是第2000次迭代时间戳滞后的情节:
答案 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的时间戳:它可能相等或更少。