I am trying to share a multi-dimensional hash over multiple threads. This hash holds 2 connected key-pairs, I need to know if they are already connected, if they are not, I need to connect them, if not, there is no need to go to the database.
use threads;
use threads::shared;
my %FLUobject2param : shared = ();
#Start a new thread for every available processor
for (my $i=0;$i<$PROCESSORS;$i++) {
threads->new(\&handlethread);
}
#Catch if these threads end
foreach my $onthr (threads->list()) {
$onthr->join();
}
sub handlethread{
...
if(not defined $FLUobject2param{$objectID}{$paramID}){
$dbh->getObject2Param($objectID,$paramID);
$FLUobject2param{$objectID}{$paramID} = 1;
}
}
I keep getting the error Invalid value for shared scalar
on the line
if(not defined $FLUobject2param{$objectID}{$paramID}){
This apparently has to do with perl's threads::shared only allowing you to share a single level of shared structure.
How would I still be able to check if this combination is already used over multiple threads ?
Autovivification is your friend most of the time, but you have to be careful about it with shared values. Modify
handlethread
:This is due do a documented limitation:
The code above checks the hash keys separately to avoid autovivification, which will plant an unshared empty hash reference in
$FLUobject2param{$objectID}
if it doesn't exist yet.Inside the conditional, we first build the appropriate scaffolding and then assign the value. Again, autovivification ordinarily handles this for you, but sharing forces us to be more deliberate.