2009-01-12
(Obsolete) Parallel::ForkManager + IPC::Shareable で複数のプロセスで変数を共有する
追記: 2011-12-20T03:18:11+09:00
結構この記事をしばしば参考にして安易にSystemV IPC 共有メモリに突っ込む事をやる人も居るようですが、IPC::Shareable 自体が長い事、メンテされてない上に、SystemV IPC 自体も古くさい手法です。大人しくファイルに書き出すなり、SQLite などを使って保存したりだとか、AnyEvent, Coro 等で書き直すとか、より簡単で確実な方法を試した方が良いでしょう。
つまるところ、この方法はお勧め出来ません。エントリ自体は削除せずに残しておきますが、そのつもりで読んで下さい。
オライリーの Perl クックブックの古い奴のレシピ 16.12 とかに書いてある内容なんですけど、自分でも試してみました。
IPC::Shareable のインストール
残念ながら現在のバージョン 0.60 はそのままだとテストが通りません。
に詳細があります。
次のパッチを当てます。
diff -cr IPC-Shareable-0.60.orig/t/38ipchv.t IPC-Shareable-0.60/t/38ipchv.t
*** IPC-Shareable-0.60.orig/t/38ipchv.t 2009-01-12 20:15:16.000000000 +0900
--- IPC-Shareable-0.60/t/38ipchv.t 2009-01-12 20:19:02.000000000 +0900
***************
*** 70,76 ****
});
%hv = ();
kill ALRM => $pid;
!
for (qw(eenie meenie minie moe)) {
$ipch->shlock();
$hv{$_} = $$;
--- 70,77 ----
});
%hv = ();
kill ALRM => $pid;
! sleep 1;
!
for (qw(eenie meenie minie moe)) {
$ipch->shlock();
$hv{$_} = $$;
IPC-Shareable-0.60.patch とかって名前にしておいて、
$ cd /path/to/dir $ wget http://search.cpan.org/CPAN/authors/id/B/BS/BSUGARS/IPC-Shareable-0.60.tar.gz $ tar xfz IPC-Shareable-0.60 $ cd IPC-Shareable-0.60 $ patch -p1 < ../IPC-Shareable-0.60.patch
としてからいつも通りにインストールします。
サンプル
下記は @data が共有できていないので、最後に dump しても空っぽです。
子プロセス各々にコピーされてしまう訳ですね。
#!/usr/bin/perl use strict; use warnings; use Data::Dump qw(dump); use Perl6::Say; use Parallel::ForkManager; my @data = (); my $pm = Parallel::ForkManager->new(10); for my $i (0..100) { my $pid; $pid = $pm->start && next; push(@data, rand($i)); $pm->finish; } $pm->wait_all_children; say dump(@data);
そこで IPC::Shareable を使うと。
#!/usr/bin/perl use strict; use warnings; use Data::Dump qw(dump); use Perl6::Say; use IPC::Shareable; use Parallel::ForkManager; my $handle = tie my @data, 'IPC::Shareable', undef, { destroy => 1 }; @data = (); my $pm = Parallel::ForkManager->new(10); for my $i (0..100) { my $pid; $pid = $pm->start && next; $handle->shlock; push(@data, rand($i)); $handle->shunlock; $pm->finish; } $pm->wait_all_children; say dump(@data);
とすると @data は shared memory に Storable で保存されるのでプロセス間で共有出来るようになります。
@data は共有変数なんで shlock, shunlock は必要です。
ちなみに tie した後に改めて初期化しないと、上手く動かないです。何もしてないのに shared memory から取得するような感じで落ちてる模様。
トラックバック - http://d.hatena.ne.jp/ZIGOROu/20090112/1231756261
リンク元
- 113 http://d.hatena.ne.jp/hogem/20110529/1306854640
- 92 http://reader.livedoor.com/reader/
- 49 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&hs=YuY&q=IE デバッグ&btnG=検索&lr=lang_ja
- 43 http://www.google.co.jp/search?q=Parallel::ForkManager&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:ja:official&client=firefox-a
- 42 http://www.google.co.jp/url?sa=t&rct=j&q=parallel::forkmanager プロセス数&source=web&cd=4&ved=0CC0QFjAD&url=http://d.hatena.ne.jp/ZIGOROu/20090112/1231756261&ei=L86nTuiPHZCemQXQjom6Dw&usg=AFQjCNFW
- 36 http://d.hatena.ne.jp/omoisan/20111018/1318944789
- 34 http://www.google.com/search?hl=ja&lr=lang_ja&ie=UTF-8&oe=UTF-8&q=mixi+openid&num=50
- 33 http://www.google.co.jp/search?hl=ja&q=Parallel::ForkManager&ie=UTF-8&oe=UTF-8
- 31 http://www.google.co.jp/search?hl=ja&rls=GGGL,GGGL:2006-39,GGGL:ja&q=actionscript2&start=10&sa=N
- 30 http://d.hatena.ne.jp/


