フォークにおけるスコープの謎
はてなアンテナのような更新チェッカを利用していて、いつもイライラさせられるのが更新チェックにかかる時間です。
そこで、子プロセスをつくりまくって、パラレルにURLのチェックをしようということで、Parallel::ForkManagerを導入してみました。
Parallel::ForkManagerとは?
perldoc.jpによると、
Parallel::ForkManager - 簡単な並列処理によるforkマネージャー
Parallel::ForkManager - 簡単な並列処理によるforkマネージャー - perldoc.jp
だそうです。
フォークを利用したプログラムはどうしてもわかりづらく&ソースがゴチャゴチャしがちですが、このParallel::ForkManagerを利用すれば難しいことを考えずにフォーク処理が記述できます。
フォーク中のスコープってどうなってるの?
で、早速このモジュールを用いて更新チェッカの書き直しをしたのですが、子プロセスでグローバルに存在するハッシュにキーをURL、値をHTTPレスポンスヘッダのLast-modifiedとしたときの登録がうまくいかない。
問題は子プロセスにおけるスコープ、名前空間あたりにあるとニラんでおります。
検証に用いたコード、実行結果は以下になります。
ソースコード
#!/usr/bin/perl use strict; use warnings; use LWP::UserAgent; use Parallel::ForkManager; use Data::Dumper; my $MAX_PROCESSES = 10; my $pm = new Parallel::ForkManager($MAX_PROCESSES); my @urls = qw(http://blog.livedoor.jp/dankogai/ http://d.hatena.ne.jp/ablabo/ http://d.hatena.ne.jp/onishi/); my %Data; $Data{'key'} = 'value'; for my $url (@urls) { my $pid = $pm->start and next; my $ua = LWP::UserAgent->new(); my $ans = $ua->head($url); print "##################\n"; $Data{$url} = $ans->last_modified || 'Nothing'; print Dumper(\%Data); print "##################\n"; $pm->finish; } $pm->wait_all_children; print "Dump Start.\n"; print Dumper(\%Data); print "Dump End.\n";
処理結果
##################
$VAR1 = {
'http://blog.livedoor.jp/dankogai/' => 1175006958,
'key' => 'value'
};
##################
##################
$VAR1 = {
'http://d.hatena.ne.jp/onishi/' => 1174045145,
'key' => 'value'
};
##################
##################
$VAR1 = {
'http://d.hatena.ne.jp/ablabo/' => 1174904497,
'key' => 'value'
};
##################
Dump Start.
$VAR1 = {
'key' => 'value'
};
Dump End.
疑問
ダンプしているメモリアドレスは同じはずなのに、各子プロセス、親プロセス中で値が変化している。
最後のダンプでは3対のURLとlast-modified情報も格納されてても良いのに。
なんでジャロ?
とりあえず今は放置。