Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Sharing multitiered hash amongst multiple threads?

by Elijah (Hermit)
on Jan 28, 2006 at 20:11 UTC ( #526204=perlquestion: print w/replies, xml ) Need Help??

Elijah has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to share a hash table across numerous threads. I am able to share the hash by a simple:

my %hash : shared;

But then I try to assign a value to it by:

{lock(%hash); $hash{$arg1}->{$arg2}->{$arg3}->{$arg4} = $arg5;}
The error I get is: Invalid value for shared scalar at

Is what I am trying to accomplish possible?

Replies are listed 'Best First'.
Re: Sharing multitiered hash amongst multiple threads?
by BrowserUk (Pope) on Jan 28, 2006 at 21:51 UTC

    You can only assign references to shared arrays and hashes into shared hashes. You can either declare them shared and assign a reference:

    my %hash : shared; my @array : shared; my %hash2 : shared; $hash{ array } = \@array; $hash{ hash } = \%hash;

    Which is simple but often inconvenient. Or you can use threads::shared::share to them before assignment.

    There are two caveats with the second approach.

    1. If you share a pre-existing hash or array that already contains data, that data is discarded.
    2. The share() sub uses a prototype which rejects attempts to share anonymous structures.

    You can make life a little easier by bypassing the prototypes using $sharedHash{ key } = &share( {} ) and $sharedHash{ key } = &share( [] ), but don't be tempted to do $sharedHash{ key } = &share( [ 'some', 'stuff', 'here' ] );because the contents will be discarded.

    An example

    #! perl -slw use strict; use threads; use threads::shared; use Data::Rmap; sub thread { my( $hashref ) = @_; rmap{ print "$_"; } $hashref; } my %hash : shared; $hash{ leaf } = 'fred'; $hash{ L1 } = &share( {} ); $hash{ L1 }{ leaf } = 'wilma'; $hash{ L1 }{ L2 } = &share( {} ); $hash{ L1 }{ L2 }{ leaf } = 'bam bam'; $hash{ L1 }{ L2 }{ L3 } = &share( {} ); $hash{ L1 }{ L2 }{ L3 }{ leaf } = 'flintstone'; threads->create( \&thread, \%hash )->join; __END__ P:\test>junk2 fred wilma bam bam flintstone

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Sharing multitiered hash amongst multiple threads?
by zentara (Archbishop) on Jan 28, 2006 at 21:04 UTC
    When you declare a hash as shared that way, it only works for the first level keys. You need to specifically declare each level as shared. Like this. I always do it manually, but you could setup some sort of loop to declare your deep levels. Remember, you need to declare them as shared before you assign a value.
    foreach my $dthread(1..$numworkers){ share ($shash{$dthread}{'go'}); share ($shash{$dthread}{'progress'}); share ($shash{$dthread}{'timekey'}); #actual instance of the thread share ($shash{$dthread}{'frame_open'}); #open or close the frame share ($shash{$dthread}{'handle'}); share ($shash{$dthread}{'data'}); share ($shash{$dthread}{'pid'}); share ($shash{$dthread}{'die'}); $shash{$dthread}{'go'} = 0; $shash{$dthread}{'progress'} = 0; $shash{$dthread}{'timekey'} = 0; $shash{$dthread}{'frame_open'} = 0; $shash{$dthread}{'handle'} = 0; $shash{$dthread}{'data'} = $data; $shash{$dthread}{'pid'} = -1; $shash{$dthread}{'die'} = 0; $hash{$dthread}{'thread'} = threads->new(\&work,$dthread); }

    I'm not really a human, but I play one on earth. flash japh

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://526204]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2019-06-25 05:23 GMT
Find Nodes?
    Voting Booth?
    Is there a future for codeless software?

    Results (101 votes). Check out past polls.