複数プロセスでの値のやりとりについて

複数プロセスでの処理を簡易的に行う場合、
私は、forkやParallel::ForkManagerを使いますが、
forkした複数の処理結果を共有する亊ができないため、
これまで、プロセス間通信を行うIPC::ShareableやIPC::Liteを使って、
forkした結果を共有できるようにしていました。

ただ、IPC系モジュールの挙動をあまり理解できていなかったため、
理解を深められたらとこのエントリーを書いてみました。

例ですが、perlモジュールのバージョンをチェックするスクリプトです。
モジュール名をfork関数を使って1プロセスずつ問い合わせ、結果をIPC::Liteモジュールで定義したグローバル変数に追加をしています。

use strict;

use IPC::Lite qw($result);
$result = undef;

my @name_list = qw( DBI CGI LWP::Simple );

foreach ( @name_list ){
    my $pid = fork;
    if ($pid) {
        wait;
    } else {
        $result->{$_}  = &working_process($_);
        exit(0);
    }
}

sub working_process {
    my $module = shift;

    my $required_module = $module;
    $required_module =~ s{::}{/}g;

    eval { require "$required_module.pm"; };
    if ($@) {
        return "not_installed";
    } else {
        no strict 'refs';
        return ${$module."::VERSION"};
    }
}

use Data::Dumper;
print Dumper( $result );

## resultに格納した値は処理の最終的にクリアしておきたいので...
foreach( keys %$result ){
    $result->{$_} = undef;
}

1;

IPCと名の付くモジュールの中で、今回はIPC::Liteの挙動を理解したかったので、モジュールを少し読んでみました。

上記の例では、各プロセスで取得したperlモジュールのバージョン値をプロセス間で共有するために、IPC::Liteではたいへんザックリですが、以下のような流れで処理されていると理解しました。

1. IPC::Liteをuseする部分で、まず今処理しているパッケージ上のグローバル変数 「result」がtie関数でフックされる。
2. フックされた「result」をキーに各プロセスで取得したモジュールのモジュール名やバージョン値などを、SQLiteにinsertする。なお、2回目以降は、「result」という名でSQLiteに登録されているデータを取得し、登録されていないものがあれば、追加でinsertを行う。

IPCを理解するには、まだ程遠い気がしますが、IPC系のモジュールももっと数多く読んで理解を深めていけたらと思います。

勘違いなどありましたら、ご指摘いただければありがたいです。

よろしくお願い致します。