Concurrency
37.1 Parallel Processes
use Parallel::ForkManager; # CPAN: simple worker pool
my $pm = Parallel::ForkManager->new(4);
$pm->run_on_finish(sub { my ($pid, $exit, $ident, $signal, $core, $data) = @_; say "$ident done: $$data" });
for my $url (@urls) {
$pm->start($url) and next; # parent continues; the child runs below
my $result = fetch($url);
$pm->finish(0, \$result); # send data back to the parent
}
$pm->wait_all_children;
# Also: MCE (Many-Core Engine: parallel map/grep/loops), Parallel::Preforkuse MCE::Map;
my @squares = mce_map { $_ * $_ } 1..1_000_000;37.2 Threads (ithreads)
Perl ithreads copy the whole interpreter per thread (heavy). They require a thread-enabled build (perl -V:useithreads). The Perl documentation discourages them for most uses: prefer processes or event loops.
use threads;
use threads::shared;
use Thread::Queue;
my $counter :shared = 0;
my $q = Thread::Queue->new(1..20);
$q->end;
my @workers = map {
threads->create(sub {
while (defined(my $item = $q->dequeue)) {
lock($counter);
$counter += $item;
}
});
} 1..4;
$_->join for @workers;
say $counter; # 21037.3 Event Loops and Async I/O
Others: AnyEvent (a common event API), POE (classic), Coro (coroutines; not maintained for newer Perls).
# Mojolicious: non-blocking I/O with promises and async/await
use Mojo::Base -strict, -signatures, -async_await;
use Mojo::UserAgent;
my $ua = Mojo::UserAgent->new;
async sub fetch_titles(@urls) {
my @tx = await Mojo::Promise->all(map { $ua->get_p($_) } @urls);
return map { $_->[0]->result->dom->at('title')->text } @tx;
}
fetch_titles('https://perl.org', 'https://metacpan.org')->then(sub { say for @_ })->wait;# Future + IO::Async (and Future::AsyncAwait: async/await keywords)
use v5.36;
use Future::AsyncAwait;
use IO::Async::Loop;
use Net::Async::HTTP;
my $loop = IO::Async::Loop->new;
my $http = Net::Async::HTTP->new; $loop->add($http);
async sub get_status($url) { my $resp = await $http->GET($url); return $resp->code }
say get_status('https://www.perl.org')->get; # ->get blocks until the Future completes