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`