Parallel::Iterator von Andy Armstrong erlaubt die gleichzeitige (parallele) Ausführung mehrerer Task auf einem Rechner mit (vorzugsweise) mehreren CPUs.
Dabei kümmert sich Parallel::Iterator um korrekte Interprozeß-Kommunikation, Forking und Verteilung auf mehrere CPUs, so daß man sich voll und ganz auf die eigentliche Aufgabe konzentrieren kann.
Ein ganz einfaches Beispiel
In diesem Beispiel wird eine Liste von Quadratwurzeln aus einer Liste von Zahlen parallel ermittelt.
Das Unterprogramm square_root, das die eigentliche Rechenarbeit ausführt, erhält als ersten Parameter den Index aus @numbers und als weiteren Parameter die zu bearbeitende Zahl.
Um die Ergebnisse im @output korrekt anzuordnen, müssen sowohl Index und Ergebnis aus square_root zurückgegeben werden.
Fall die Reihenfolge keine Rolle spielt, kann der Index in der Rückgabeliste entfallen.
iterate_as_array kümmert sich um die Parallelisierung des Unterprogramms square_root.
#!/usr/bin/perl use warnings; use strict; use Parallel::Iterator qw( iterate_as_array ); # Indizes: 0 1 2 3 4 5 6 my @numbers = qw/ 1 4 9 16 25 36 49 /; my @output = iterate_as_array( \&square_root, \@numbers ); print join("\t", @output), "\n"; sub square_root { my ($index, $number) = @_; my $sr = sqrt($number); return ($index,$sr); }
Das Programm erzeugt folgende Ausgabe:
1 2 3 4 5 6 7
Beispiel: Mehrere URLs parallel holen
Dieses Beispiel habe ich aus dem Beitrag Parallel map with Parallel::Iterator von David Golden übernommen.
#!/usr/bin/perl use strict; use warnings; use LWP::UserAgent; use Parallel::Iterator qw/iterate_as_array/; # shamelessly stolen from # http://www.dagolden.com/index.php/935/parallel-map-with-paralleliterator/ my $ua = LWP::UserAgent->new( ); # this worker fetches a page or returns undef my $worker = sub { my $index = shift; my $url = shift; my $resp = $ua->get($url); return undef unless $resp->is_success; return $resp->decoded_content; }; # this gets a list of pages and fetches them in parallel my @urls = qw( http://www.yahoo.de http://www.perl-howto.de http://www.perl.org ); # Fetch pages in parallel my @pages = iterate_as_array( $worker, \@urls ); foreach my $page ( @pages ) { # Do something with "$page"; # ... }
Siehe auch:
- Parallel::Iterator
- Parallel map with Parallel::Iterator
- Beispiel: cpan-faces.pl
- Beispiel: speedy.pl
Hi Thomas,
I discovered this module recently and wrote a little helper function to be able to use it in a map-y way, using functions that only get one argument.
Here is my post talking about it.