tokuhirom's Blog

fork したくてたまらない貴方に。

こんにちは、金曜日の担当、素敵なレディーことtokuhiromです。

最近 Perl Mongers の注目を集めている system call といえば fork(2) ですが、fork ひとつとってもいろいろ方法があるのが TIMTOWTDI をモットーとする perl のいいところです。というわけで、いろいろな fork の方法についてみんなで調べてみました。

数ある fork する方法の中から、あなたの life style にあった fork 術を探すということは、あなたの人生を豊かにします。Enjoy!

# =========================================================================
# How do you like fork(2)
#
# =========================================================================
use strict;
use warnings;
 
my $type = shift or die "Usage: $0 type";
love_fork($type);
print "YO!\n";
 
sub love_fork {
    my $type = shift;
 
    my $code = +{
        simple => sub {
            fork();
        },
        'open' => sub {
            open my $fh, '|-';
        },
        'syscall' => sub {
            require 'syscall.ph';
            syscall(&SYS_fork);
        },
        'IO::File' => sub {
            require IO::File;
            IO::File->new('|-');
        },
        dynaloader => sub {
            require DynaLoader;
            DynaLoader::dl_install_xsub(
                "myfork",
                DynaLoader::dl_find_symbol(
                    DynaLoader::dl_load_file("libc.so"),
                    'fork'
                ),
            );
            myfork();
        },
    }->{$type};
    die "unknown type : $type" unless $code;
    $code->();
}

http://gist.github.com/78106

【追記】
これで終わりだと不親切なので解説。

open my $fh, '|-';

は fork しちゃいます。2引数の open はこれ以外にも pipe ひらいちゃったりできるので、使わないようにするのが基本です。Perl::Critic をつかっていると、2引数の open を発見できて便利です。

IO::File->new(); は実は中身はたんに open() をよんでいるだけなので、IO::File をつかうと同じように fork できてしまいます。

syscall() くみこみ関数は、system call を普通によべてしまいます。実際のシステムコールの番号なんかは syscall.ph をみればわかります。

最後に DynaLoader をつかった方法。DynaLoader は XS を読みこむためにつかわれるモジュールですが、ここでは libc.so をよみこませています。DynaLoader::dl_install_xsub() をつかうと、任意のコードを CV に変換できるので大変便利です(pure perl でこれができる方法はアリやナシや)。

thanks to id:kazuhooku & id:yappo & id:hirose31