Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
Hi All,
I'm very new to PERL threading.. and got a bit struck in implementing a ThreadPool. I saw the Thread::Pool module, but since that has the implementation for older thread model, I decided to try and implement one on my own(just an experiment). The idea is the same - put all the work in a queue and a fixed number of threads should work on it, till the queue is emptied.
Here is my module :my $pool = Custom::Utility::ThreadPool->new(maxThreads => 5); $pool->enqueue(&func, $arg1, $arg2...); $pool->start; $pool->blockTillCompletion;
The problem I'm facing is - in the work subroutine, every thread is getting its own copy of $pool it seems. Say if there are 10 items in the workQueue, all threads executing work subroutine seems to get a copy of the workQueue and each proceeds to execute all 10 of them. The expected is the 10 work items must be shared and completed. I tried to share @{$pool->workQueue} but wasn't able to. PERL gave me compile errors saying 'invalid value for shared scalar'. I'm using PERL5.8.8. Can anybody help me in overcoming this, please.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->{wor +kQueue}} ."\n"; #problem here; every thread seems to have its own co +py 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;
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Implementing Custom ThreadPool
by zwon (Abbot) on May 20, 2012 at 10:36 UTC | |
Re: Implementing Custom ThreadPool
by BrowserUk (Patriarch) on May 20, 2012 at 14:24 UTC | |
Re: Implementing Custom ThreadPool
by Khen1950fx (Canon) on May 20, 2012 at 13:09 UTC |
Back to
Seekers of Perl Wisdom