Hi, chris212.
The following is a simplier form of testa. The main process creating worker threads is also the one joining them. What I've done is merged the input and ouput routines and named it manager.
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;
}
Regards, Mario.