I've been beating my head against the wall trying to get this to work with no
success, so I figured I'd turn to the experts.

I'm trying to manage a pool of threads, and I figured the best way to 
instruct the threads to do work and figure out when they are finished is
through a hash set that each thread looks at. 

Excuse my psuedo-code, but something sort of like this is what I'm trying to
accomplish:

shared: $hash{thread1}{state}

parent:
        foreach $row ( keys %hash) { 
                if ($hash{$row}{state} eq 'idle') {
                        $hash{thread1}{state} = 'go';
                }
        }

thread:
        while(1) { 
                if ($hash{mytid}{state} eq 'go') { 
                        do_work; 
                }; 
        }

Before I proceed, if anyone has *any* better ideas on how to do this, by all
means let me know. I'm open to suggestions. :) Also, I'd like to note that I
have had successes in sharing scalars, but this is my first forray into sharing
hashes. This program launches hundreds of threads if I set it up fire-and-
forget style, so I need to use a pool of threads or else it uses hundreds of 
megs of memory in just minutes. Fork()ing doesn't work properly since I'm
unable to share state information (without using serialization -- I want to 
avoid such hackery if possible).

So, now on to the problem. I have written a test program to demonstrate the
problem that I'm having. Here is the test program:

use threads;
use threads::shared;

my %test : shared = ();

$test{'a'} = "a = a";
$test{'a'}{'b'} = "a+b = c";

print "[parent] test->a = $test{'a'}\n";
print "[parent] test->a->b = $test{'a'}{'b'}\n";

my $thread = async {
        $test{'a'}{'b'} = "a+b = t";
        print "[thread] test->a->b = $test{'a'}{'b'}\n";
        return;
};

# Give the thread a moment to work.
sleep 1;
print "[parent] test->a->b = $test{'a'}{'b'}\n";

Here is the output:
D:\scripts>perl test
[parent] test->a = a = a
[parent] test->a->b = a+b = c
[thread] test->a->b = a+b = t
[parent] test->a->b = a+b = c

I give the parent a moment to sleep to ensure that the thread does its work
but as you can see from the output, when the thread sets $test{a}{b} it 
obviously doesn't set it for the parent.

Now, if I turn on strict the program fails altogether since I'm trying to set
a text string as a hash ref which doesn't work in the strict world.

Next if I modify the code like this:
#use strict;
use threads;
use threads::shared;

my %test : shared = ();

$test{'a'}{'b'} = c;

When I run the program here's what happens:

D:\scripts>perl test
Invalid value for shared scalar at test line 7.

Very frustrating! I'm using ActivePerl 806 on a Windows 2000 Server system.
Because of this, I can't use forks.pm.

Is there a solution to this, or is there a better way to do the pooling and
process handling that I want?

Any advice would be most appreciated.

Reply via email to