my $pool = Custom::Utility::ThreadPool->new(maxThreads => 5); $pool->enqueue(&func, $arg1, $arg2...); $pool->start; $pool->blockTillCompletion; #### package Custom::Utility::ThreadPool; use strict; use threads; use threads::shared; sub new { my $class = shift; my %params = @_; my $pool = { maxThreads => $params{maxThreads}, workQueue => undef, jobs => undef, }; bless($pool, $class); return $pool; } sub work { my $pool = shift; while(my @args = shift @{$pool->{workQueue}}) { print "ID=" .threads->self()->tid() ." : WorkQueue = " .@{$pool->{workQueue}} ."\n"; #problem here; every thread seems to have its own copy of @{$pool->{workQueue}} my $code = shift @args; &$code(@args); } } sub start { my $pool = shift; # ensure that start is executed only once on a ThreadPool instance return if $pool->{jobs}; # make sure there undefs are enqueued to the workQueue so that child threads can # complete the process rather than being blocked on Thread::Queue's dequeue push @{$pool->{workQueue}}, ((undef) x $pool->{maxThreads}); @{$pool->{jobs}} = map { threads->create(\&work, $pool) } 1..$pool->{maxThreads}; } sub enqueue { my ($pool, $code, @args) = @_; # default the namespace to the caller's package if only a name is # specificed instead of a code or its reference $code = caller() ."::$code" if !ref($code) && $code !~ /::/; # push it to the workQueue list push @{$pool->{workQueue}}, [$code, @args]; } sub blockTillCompletion { my $pool = shift; $_->join() for @{$pool->{jobs}}; } 1;