うまいぼうぶろぐ

linuxとhttpdとperlのメモ

perlでfork

use warnings;
use strict;
my $pid = fork;
if ($pid) {
  ## parant process
}
else {
  ## child process
}
waitpid($pid,0);

waitpidをしなかったら、子プロセスが残っていても親プロセスは先に終わってしまう。

  • 指定した数だけfork
my $max_process = 10;
my @pids;
for ( 1 .. $max_process ) {
  my $pid = fork;
  push @pids, $pid;
  die "can't fork child process" if ! defined $pid;
  if ($pid) {
    ## parent process
    next;
  }
  else {
    ## child process
    exit;
  }
}
waitpid($_, 0) for @pids;

親プロセスはforkだけして、各処理は子プロセスで行う。子プロセスの処理が終わったあとには必ずexitすること。そうしないと、子プロセスも次のfor loop に 行ってforkするので孫プロセス、曾孫プロセス ... という風に指数関数的に増えていく。↑のやりかただと、2^$max_process - 1 だけプロセスがforkされる。

追記

cpanモジュール頼ったほうが良いな。なんで気づかなかったんだ。。。

Parallel::ForkManager
use Parallel::ForkManager;
my $pm = Parallel::ForkManager->new($max_proc) or die;
for my $host (@hosts) {
  $pm->start and next;
  hoge($host);
  $pm->finish;
}
$pm->wait_all_children;