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`