views:

69

answers:

1

Tom Christiansen's example code (à la perlthrtut) is a recursive, threaded implementation of finding and printing all prime numbers between 3 and 1000.

Below is a mildly adapted version of the script

#!/usr/bin/perl
# adapted from prime-pthread, courtesy of Tom Christiansen

use strict;
use warnings;
use threads;
use Thread::Queue;

sub check_prime {       
    my ($upstream,$cur_prime) = @_;     
    my $child;
    my $downstream = Thread::Queue->new;

    while (my $num = $upstream->dequeue) {          
        next unless ($num % $cur_prime);

        if ($child) {

            $downstream->enqueue($num);

        } else {

            $child = threads->create(\&check_prime, $downstream, $num);

            if ($child) {

                print "This is thread ",$child->tid,". Found prime: $num\n";

            } else {

                warn "Sorry. Ran out of threads.\n";
                last;
            }
        }
    }

    if ($child) {
        $downstream->enqueue(undef);
        $child->join;
    }
}

my $stream = Thread::Queue->new(3..shift,undef);
check_prime($stream,2);

When run on my machine (under ActiveState & Win32), the code was capable of spawning only 118 threads (last prime number found: 653) before terminating with a 'Sorry. Ran out of threads' warning.

In trying to figure out why I was limited to the number of threads I could create, I replaced the use threads; line with use threads (stack_size => 1);. The resultant code happily dealt with churning out 2000+ threads.

Can anyone explain this behavior?

+3  A: 

From the threads documentation:

The default per-thread stack size for different platforms varies significantly, and is almost always far more than is needed for most applications. On Win32, Perl's makefile explicitly sets the default stack to 16 MB; on most other platforms, the system default is used, which again may be much larger than is needed.
By tuning the stack size to more accurately reflect your application's needs, you may significantly reduce your application's memory usage, and increase the number of simultaneously running threads.
Note that on Windows, address space allocation granularity is 64 KB, therefore, setting the stack smaller than that on Win32 Perl will not save any more memory.

weismat
This is interesting. Using `$child->get_stack_size;` I get `8096`. I'm assuming that's in bytes, right?
Zaid
The windows documentation (http://msdn.microsoft.com/en-us/library/ms686774%28VS.85%29.aspx) mentions also 64 kByte as a typical size, to find the actual size you need to call the GetSystemInfo. This is something which might even be CPU architecture dependend.
weismat
This link (http://www.perlmonks.org/?node_id=31432) might help you to get the data from perl.
weismat