LoginSignup
11
10

More than 5 years have passed since last update.

[perl] Parallel::ForkManager で簡単に複数プロセスをforkする

Posted at

セールスポイント:
* STDOUT / STDERR やユーザデータの受け取りをコールバックで行えるようにしてあります。
* child process が die したときにも $pm->finish() を呼ぶようにしています。
* なにげにハンドルと変数代入のperl IO レイヤのサンプルにもなっています。

#!/usr/bin/env perl

use utf8;
use strict;
use warnings;
use Data::Dumper;
use Carp qw(croak);

use Encode qw(decode_utf8);

use Parallel::ForkManager;

sub say { print $_[0], "\n"; }

our $N_CHILDREN = 5;
my $pm = Parallel::ForkManager->new($N_CHILDREN);

# callback when child process exit or die.
$pm->run_on_finish( sub {

    my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;

    if (defined $data_structure_reference) {
        #print Dumper($data_structure_reference);
        print STDOUT Encode::decode_utf8($data_structure_reference->{'stdout'});
        print STDERR Encode::decode_utf8($data_structure_reference->{'stderr'});
        say "Client terminating with data => ". $data_structure_reference->{'i'};
    }

    say "EXCEPTION: child PID: $pid with $exit_code" if $exit_code ;
    say "";

});


foreach my $i (0..9) {

    my $pid = $pm->start and next;

    my ($stdout, $stderr) = ('','');

    $SIG{__DIE__} = sub { $pm->finish( -1, { i => $i, 'stdout'=>$stdout, 'stderr'=>$stderr } ); };

    close STDOUT;
    close STDERR;
    open STDOUT, ">:scalar:utf8", \$stdout or $pm->finish(-1);
    open STDERR, ">:scalar:utf8", \$stderr or $pm->finish(-1);
    STDOUT->autoflush(1);
    STDERR->autoflush(1);

    say "Client $$ starting...";

    croak "Client died" if $i % 2 == 0 ;

    sleep 10; # do something useful instead!

    $pm->finish( 0, { i => $i, 'stdout'=>$stdout, 'stderr'=>$stderr } );

}

$pm->wait_all_children;

say "Parent process after all child has finished";

__END__
11
10
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10