2017-08-27 48 views
1

我試圖使用fileno爲我的線程創建一個文件句柄表,並且遇到了我無法理解的情況。考慮下面的代碼:fileno和引用弱化混淆

use strict; 
use Data::Dumper; 
my %fhh; #this is shared, but that's not important for my issue 
open my $fh , '>', 'out1.txt' ; 
$fhh{1} = fileno $fh; 
open my $fh , '>', 'out2.txt' ; 
$fhh{2} = fileno $fh; 
open my $fh , '>', 'out3.txt' ; 
$fhh{3} = fileno $fh; 
open my $fh , '>', 'out4.txt' ; 
$fhh{4} = fileno $fh; 
print Dumper \%fhh; 

輸出我得到的是:

$VAR1 = { 
      '4' => '9', 
      '1' => '6', 
      '3' => '8', 
      '2' => '7' 
     }; 

到目前爲止好,不幸的是我需要生成一個未知的句柄數的,所以我嘗試下面的代碼:

use strict; 
use Data::Dumper; 
my %fhh; 
foreach my $i (1 .. 4){ 
    my $file = "out" . $i . ".txt"; 
    open my $fh , '>', $file ; 
    $fhh{$i} = fileno $fh; 
} 
print Dumper \%fhh; 

在這裏,我得到的輸出:

$VAR1 = { 
      '4' => '10', 
      '1' => '10', 
      '3' => '10', 
      '2' => '10' 
     }; 

所以有些事情是錯誤的,也許這裏$ fh變得虛弱並失去了?所以我嘗試以下操作:

use strict; 
use Data::Dumper; 
my %fhh; 
my @mfw; 
foreach my $i (1 .. 4){ 
    my $file = "out" . $i . ".txt"; 
    open my $fh , '>', $file ; 
    push @mfw, $fh; 
    $fhh{$i} = fileno $fh; 

} 
print Dumper \%fhh; 

這裏的輸出是正確再次,像在第一個例子,所以現在看來​​,這的確是一個問題弱化,但後來爲什麼不是這種情況發生在第一個例子嗎?我每次都重新定義$ fh,即使我圍繞{}中的整個塊仍然可以正常工作,有人可以向我解釋發生了什麼事嗎?
我在perl上5.14如果重要的話

回答

3

my $fh的範圍是封閉塊。該變量是文件句柄的唯一引用。當文件句柄被銷燬時,文件被關閉,並且文件描述符號碼可以被重新用於下一個文件。 FD只是一個整數,它沒有保存文件的魔力。

通過保持對數組中已打開的文件句柄的引用,您已經延長了文件句柄的生存期。因此每個新文件都會得到一個新的FD號碼。

+0

嗯我明白了。我試着將我的第一個例子分成4個塊,問題確實發生。所以當我在同一個塊中重新定義一個變量時,以前的內容不會被削弱? – Nullman

+0

@Nullman代碼中沒有弱引用。 Perl使用引用計數來管理垃圾收集。如果對象的引用計數降至零,則該對象將被銷燬。 'my'的變量只存在於塊的末尾。文件描述符不是Perl可以識別的引用。在你的最後一個例子中,數組一直引用文件句柄,所以它們不會被銷燬。 – amon

+1

所以當我在第一個例子中重新定義$ fh時,先前打開的文件句柄仍然在內存中的某個地方打開,直到塊結束,但是在循環中它在每次迭代結束時都會關閉?這是否意味着循環的每次迭代都是一個單獨的塊? – Nullman