2010/02/17(水)[perl] forkで子供がたくさん
子プロセスを作って並列処理
表題のとおり。自動計測系の構築などで、監視する側と実行する側とに分離したいとき、forkを使うのが易いようです。
Windowsなら、Active Perlのperlforkを見ると、いろいろと例が載っています。
TrackBack先のMagic Voxで見かけたので、記事を書いてみます。
自分で確認した記録でもありますが...なお、Windows7 Ultimatex64 + Active Perl v5.10.0で試しました.
コーディング例
use POSIX ":sys_wait_h"; $| = 1; my ($pid, $n) ; $n = 4 ; do { $pid = fork ; if (!defined $pid) { die "fork fairule...\n" ; } elsif ($pid==0) { # child print "I'm a child $n/pid=$pid \n"; sleep 10 - $n ; exit $n ; } else { print "create process $pid\n"; } --$n; } while ($n>0) ; my $killid ; sleep 1; do { # $killid = wait(); $killid = waitpid(-1, WNOHANG); print "child $killid is dead and said $?\n" unless $killid==0; } while ($killid!=-1) ; print "Terminate test PGM.\n" ; exit ;
親としては、子が消えるまで待ったり、よそからの要求で殺したりするわけですね。とりあえずは、forkで分岐するところをテンプレート的にお試ししました、というだけで。
実行例
>perl tst_fork01.pl create process -4900 I'm a child 4/pid=0 create process -888 I'm a child 3/pid=0 create process -2364 I'm a child 2/pid=0 create process -2004 I'm a child 1/pid=0 child -4900 is dead and said 1024 child -888 is dead and said 768 child -2364 is dead and said 512 child -2004 is dead and said 256 child -1 is dead and said -1 Terminate test PGM.
ただし、Perl で複数個のワーカープロセスを動かして処理を行う場合のコードとして例が挙がっているように、まじめにやる場合はこちらを参照したほうがよさそうです。SIGトラップして云々・・・。まだまだ勉強不足のようで('A`