threads::shared and nested hash

threads::shared and nested hash

am 18.09.2007 15:31:41 von Graham Drabble

Hi,

I have a list of IP addresses in @nes. I need to create a hash in
%alarms where the keys are the IP addresses and the values are a hash
with keys being an event and value the severity.

I have done this as follows

use strict;
use warnings;

my @nes = ('172.18.0.1','172.18.0.2');

my %alarms;

foreach my $ne (@nes){
$alarms{$ne}{'Disconnected'} = 5;
$alarms{$ne}{'LOS.1'} = 3;
check_colour($ne);
}

I am now trying to use this in a threaded environment and need %
alarms to be shared. I have tried

use strict;
use warnings;
use threads;
use threads::shared;

my @nes = ('172.18.0.1','172.18.0.2');

my %alarms : shared;

foreach my $ne (@nes){
$alarms{$ne}{'Disconnected'} = 5;
$alarms{$ne}{'LOS.1'} = 3;
check_colour($ne);
}

This says that "Invalid value for shared scalar at ems.pl line 11". I
guess I need to use &share({}) somewhere but I can't see how.

--
Graham Drabble
http://www.drabble.me.uk/

Re: threads::shared and nested hash

am 18.09.2007 17:09:54 von Ben Morrow

Quoth Graham Drabble :
> Hi,
>
> I have a list of IP addresses in @nes. I need to create a hash in
> %alarms where the keys are the IP addresses and the values are a hash
> with keys being an event and value the severity.

>
> I am now trying to use this in a threaded environment and need %
> alarms to be shared. I have tried
>
> use strict;
> use warnings;
> use threads;
> use threads::shared;
>
> my @nes = ('172.18.0.1','172.18.0.2');
>
> my %alarms : shared;
>
> foreach my $ne (@nes){
> $alarms{$ne}{'Disconnected'} = 5;
> $alarms{$ne}{'LOS.1'} = 3;
> check_colour($ne);
> }
>
> This says that "Invalid value for shared scalar at ems.pl line 11". I
> guess I need to use &share({}) somewhere but I can't see how.

Autoviv (the automatic creation of intermediate hashes/arrays whenever
you use them) on a shared hash doesn't work. Given that this bug is
mentioned in the perldoc, I guess it's rather hard to fix. You need to
explicitly create and share the intermediate hashes:

foreach my $ne (@nes) {
$alarms{$ne} = &share({});
$alarms{$ne}{'Disconnected'} = 5;
$alarms{$ne}{'LOS.1'} = 3;
check_colour($ne);
}

Hmmm, that &share({}) is really smelly, in the perldoc or no... I'd
probably rather write it as

foreach my $ne (@nes) {
my %ne : shared;

$ne{'Disconnected'} = 5;
$ne{'LOS.1'} = 3;

$alarms{$ne} = \%ne;
check_colour($ne);
}

which is arguably cleaner anyway.

Ben