■2005-06-27
* [Perl][メモ] threadsとunlink
「終了した thread であっても、reference counterなどに影響を与えているような感じがします」(thread は join() では死なない より)。具体的には、threadsを使ったときに子スレッドを明示的にundefしないとファイルをunlinkできないという話(ただしActivePerl 5.8.1以降)。要は、開いているファイルハンドルが子スレッドにコピーされたままなのでunlinkできないわけですね。
# ActivePerl 5.8.1以降
package IO::File;
sub DESTROY {
my $tid = threads->tid;
print "destroyed($tid)\n";
}
package main;
my $fname = './test.dat';
my $fh = IO::File->new(">$fname");
{ # ←このブロックをコメントアウトする
my $th = threads->new(sub{ });
# ↑$fhが子スレッドにコピーされる
$th->join();
} # ←このブロックをコメントアウトする
$fh->close;
print "now unlink\n";
unlink($fname) or warn $!;
# ブロックなし
# now unlink
# Permission denied at unlink.pl
# destroyed(1)
# destroyed(0)
# ブロックあり
# destroyed(1)
# now unlink
# destroyed(0)
元記事にあるようにundef $thするか、上記のように$thのスコープを限定させてGCを発動すれば子スレッド内(tid=1)のファイルハンドルも閉じられるのがわかります。
ちなみに、joinやdetachをしないとスレッド内のデータはclean upされません。そのためjoinable状態の$thをundefしても、ファイルハンドルは閉じられないようです。
* [メモ] 備忘録
上ので思い出しました。ディスクロージャとithreadsでPerlクラッシュ関連をithreadメモに追記しておくこと。
奥崎謙三、亡くなられたんだ。 あー、「神様の愛い奴」を知人から借りっぱなしで、まだ観てないことを思い出した!
[]

