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.
my $pool = Custom::Utility::ThreadPool->new(maxThreads => 5); $pool->enqueue(&func, $arg1, $arg2...); $pool->start; $pool->blockTillCompletion;
Here is my module :
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;
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.

In reply to Implementing Custom ThreadPool by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.