近頃版/another blog@hatena/Wiki/BBS
< Path Finding IV | 今日のところ。 >
以前のルーチンには親(呼出し元)資源を握りっぱなしのままforkしてしまうという大きな問題があった。thread使えばそのへんは解決するのだが、敢えてforkでやるために工夫してみたコード:
sub new_with_fork
{
my $class = shift;
my $callback;
if($_[0] eq 'callback'){
shift;
$callback = shift;
}
my($parent,$child) = IO::Socket->socketpair(AF_UNIX,SOCK_STREAM,0);
unless($parent){
return undef;
}
my $pid = fork();
if($pid) { # Parent
$parent->close();
bless $child ,$class->parentClass();
my $prof = \%{*$child};
$prof->{pid} = $pid;
return $child;
}elsif(defined $pid) { # Child
$child->close();
bless $parent,$class->childClass;
if(ref($callback)){
&$callback();
}
$class->child_main($parent,@_);
exit(1); # never come here.
}
}
なんのことはない、生成直後に親側の資源を解放するためのコールバック関数を呼ぶようにしただけだ。
呼出し側(スタブ生成元)の記述はこんな感じ:
new_with_fork ChildClass('callback' => \&resource_release_function,@args);
これだとコールバック関数に引数を与えられないとかの問題も存在するがとりあえずそれは目をつぶろう。グローバルに変数を持ちたくなければクロージャーを使えということで。