Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

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
Domain Nodelet?
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 drinking their drinks and smoking their pipes about the Monastery: (1)
As of 2021-09-24 05:32 GMT
Find Nodes?
    Voting Booth?

    No recent polls found