2016-09-22 83 views
5

我看到Perl的Time::HiRes模塊報告的時間戳有一些奇怪的行爲。爲什麼這些時間戳與Perl Time :: HiRes不同?

我有一個腳本,達到三星時間戳:

  1. 獲取時間戳和Time::HiRes::time
  2. 創建一個新的文件,並獲取其修改時間與Time::HiRes::stat
  3. 獲取時間戳和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

+0

'$ t0- $ fs,「」,$ t1- $ fs'顯示$ t0和$ t1都非常接近,遠遠超過$ fs –

回答

5

如DOC here提到這可能是因爲在這兩種時間戳精度的差異:

由於統計或LSTAT但 與訪問/修改/修改文件時間戳在一秒分辨率, 如果歌劇ting系統和文件系統都支持這樣的 時間戳。要覆蓋標準的stat():

use Time::HiRes qw(stat); 

檢驗的&時間::高分辨率:: d_hires_stat值找出操作系統 是否支持亞秒級文件時間戳:大於零值表示 肯定。不幸的是,沒有簡單的方法可以確定 文件系統是否支持這樣的時間戳。 UNIX文件系統經常這樣做; NTFS 確實; FAT不(FAT時間戳粒度爲兩個秒)。

的&時間::高分辨率零 返回值:: d_hires_stat意味着 時間::高分辨率:: STAT是用於CORE無操作直通:: STAT()(和 同樣爲LSTAT),和因此時間戳將保持整數。 即使Time :: HiRes :: d_hires_stat不爲0,文件系統也不會執行亞秒 時間戳,也會發生同樣的情況。

在任何 情況下都不會期望納秒分辨率,甚至不會有微秒的 分辨率。還要注意,修改/訪問時間戳可能具有不同的分辨率,並且它們不需要被同步,例如,如果 操作是

write 
stat # t1 
read 
stat # t2 

從T2訪問時間戳不必大於的修改從T1 時間戳:它可能是等於或小於