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.