use strict; use warnings; use threads; use Thread::Semaphore; use Time::HiRes qw(time); my $iterations = 100; my $chunksize = 50; my $threads = 5; my $results = "s.txt"; my $s = Thread::Semaphore->new($threads); my %data = (); foreach ('a'..'z') { $data{$_} = $_ x 200; } test(); sub test { my $t = time; manager(); printf "duration: %0.02f secs.\n", time - $t; } sub work { my ($data) = @_; my @ret = (); foreach my $chunk (@$data) { my %output = (); foreach my $key (keys %$chunk) { if ($key eq '.') { $output{$key} = $$chunk{$key}; next; } my $val = $$chunk{$key}; my $uc = uc($key); $val =~ s/$key/$uc/g; $output{$key} = $val; } push @ret, \%output; } my $buf = ''; foreach my $data (@ret) { foreach my $key (sort keys %$data) { $buf .= $$data{$key}; } $buf .= "\n"; } $s->up(); return $buf; } sub manager { my @q; open my $fh, '>', $results or die "open error: $!\n"; foreach my $a (1..$iterations) { my @chunk = (); foreach my $b (1..$chunksize) { my %_data = %data; $_data{'.'} = $a * $b; push @chunk, \%_data; } $s->down(); push @q, threads->create('work', \@chunk); while (@q && $q[0]->is_joinable) { my $output = shift(@q)->join(); print {$fh} $output; } } while (@q) { my $output = shift(@q)->join(); print {$fh} $output; } close $fh; }