Why is array pushed in thread sub not set after join?

D

David Karr

Perl 5.10.0 on Cygwin 1.5.25.

I have a loop where each iteration makes 5 independent REST calls. After each of those 5 calls, some data from the result is pushed onto an array that is declared before the loop. After the loop, I iterate through the resulting array. When this is implemented without threads, this works fine.

I decided that since each of those 5 calls are independent, it might be faster if I executed each of them in a thread, and then "join"ed each of the threads at the end of the iteration, using the "void" context, as I don't need a return value from each of those (just the side effect of pushing onto the array).

the print statements seemed to show this was working fine, and it did appear to go faster, but after the loop I checked the size of the array whose contents had been pushed from each of those threads, and it was size 0.

I also tried adding "use threads::shared;" after my "use threads;" declaration, but that had no effect.

Is there anything obviously or likely wrong with my approach?

The changes I made to implement threads were pretty simple. I just added aline like this before each of the 5 blocks:

my $xxthread = threads->create(sub {

with a matching "});" at the end of each of the 5 blocks, and then a set of5 "$xxthread->join();" calls at the end of the iteration.

There were 5 different "xx" values, as I stored each thread in a separate variable.
 
W

Willem

David Karr wrote:
) Perl 5.10.0 on Cygwin 1.5.25.
)
) I have a loop where each iteration makes 5 independent REST calls. After
) each of those 5 calls, some data from the result is pushed onto an array
) that is declared before the loop. After the loop, I iterate through the
) resulting array. When this is implemented without threads, this works
) fine.
)
) I decided that since each of those 5 calls are independent, it might be
) faster if I executed each of them in a thread, and then "join"ed each of
) the threads at the end of the iteration, using the "void" context, as I
) don't need a return value from each of those (just the side effect of
) pushing onto the array).

It would have been easier if you had the threads return the wanted value,
and then pushing that into the array when you 'join' them:

) the print statements seemed to show this was working fine, and it did
) appear to go faster, but after the loop I checked the size of the array
) whose contents had been pushed from each of those threads, and it was
) size 0.
)
) I also tried adding "use threads::shared;" after my "use threads;"
) declaration, but that had no effect.
)
) Is there anything obviously or likely wrong with my approach?

You probably need to specifically mark the array as a shared variable.

) The changes I made to implement threads were pretty simple. I just added
) a line like this before each of the 5 blocks:
)
) my $xxthread = threads->create(sub {
)
) with a matching "});" at the end of each of the 5 blocks, and then a set
) of 5 "$xxthread->join();" calls at the end of the iteration.
)
) There were 5 different "xx" values, as I stored each thread in a separate
) variable.

If you have 5 different 'xx' values, you're usually better off using an
array.

Returning the values and pushing them into an array when joining is a lot
cleaner, as it doesn't require sharing variables:

my @results = map { $_->join } map { threads->create(sub {
return get("http://www.example.invalid/$_.html");
}) } qw/some thing or other to get/;

And even if the five functions do something wildly different,
you can still do it like that, using an array of anon-subs:

my @results = map { $_->join } map { threads->create($_) } (
sub { return get('something_one'); },
sub { return do_something('two'); },
sub { $result = foo(); return $result; },
sub { return another_function() + 100; },
sub { return 1 + 2; }
);

HTH, HAND.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,037
Latest member
MozzGuardBugs

Latest Threads

Top