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

I am trying to use threads while assigning an array to a hash and another array to a hash of hash.
#!/usr/bin/Perl use strict; use threads; use threads::shared; my %hash :shared; my %hash1 :shared; my $a = "abcdef"; my $b = "ghighi"; my $len = length($a)-2; # Define the number of threads my $num_of_threads = 2; # use the initThreads subroutine to create an array of threads. my @threads = initThreads(); # Loop through the array: foreach(@threads){ # Tell each thread to perform our 'doOperation()' subr +outine. $_ = threads->create(\&doOperation); } # This tells the main program to keep running until all threads have f +inished. foreach(@threads){ $_->join(); } print "\nProgram Done!\nPress Enter to exit"; $a = <>; ####################### SUBROUTINES ############################ sub initThreads{ my @initThreads; for(my $i = 1;$i<=$num_of_threads;$i++){ push(@initThreads,$i); } return @initThreads; } sub doOperation{ # Get the thread id. Allows each thread to be identified. my $id = threads->tid(); my $i = 0; while($i < 2) { my $split = substr($a, $i, $len); my $split1 = substr($b, $i, $len); my $affix = substr($split, 0, $len-1); my $postfix = substr($split, 1, $len-1); my $affix1 = substr($split1, 0, $len-1); my $postfix1 = substr($split1, 1, $len-1); print "$affix\t$postfix\n"; lock(%hash); #lock(%hash1); $hash{$affix} = threads::shared::shared_clone([$affix1]); print "$hash{$affix}\n"; #$hash1{$affix}{$postfix} = threads::shared::shared_clone([$af +fix1]); This is where the problem is. How can I assign an array to a +hash of hash $i++ } print "Thread $id done!\n"; # Exit the thread threads->exit(); } Thread 1 terminated abnormally: Invalid value for shared scalar.
How can I assign an array to a hash of hash when using threads.

Replies are listed 'Best First'.
Re: Multithreading How do I share hash of hash of arrays
by BrowserUk (Patriarch) on Jan 22, 2015 at 21:48 UTC

    The code you've posted is incomplete and does not run. Thus; for anyone to help you, they must first make the snippet run. That's lazy & rude.

    Second, your annotations are wrong. You claim this line "works fine":

    $hash{$a} = threads::shared::shared_clone(@array); ## This part works +fine

    But in truth it produces the error: Usage: shared_clone(REF) at ...

    So, if you want some help; first make your code compile clean under strict & warnings; and then make sure that it does what you say it does. Then come back.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
    In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
Re: Multithreading How do I share hash of hash of arrays
by Jenda (Abbot) on Jan 24, 2015 at 01:17 UTC

    What are the expected sizes of the data structures? It may easily be the case that the right place for the data is a database, not an ad hoc, shared, frail data structure.

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

      What are the expected sizes of the data structures? It may easily be the case that the right place for the data is a database,

      Size is the wrong criteria here.

      A large, shared data structure will out-perform a "database" -- even an in-memory DB -- if the preponderance of accesses are read-only.

      not an ad hoc, shared, frail data structure

      Why does a (usually considered, "very reliable"), Perl data-structure, suddenly become "unreliable", because it is shared?


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

        When you attempt to update it. It's easy to forget a lock or (in case of a deep structure) add something that's not shared.

        Size is one of the criteria. Once it all doesn't fit in memory ... In either case with so little information, we can just give suggestions.

        Jenda
        Enoch was right!
        Enjoy the last years of Rome.

Re: Multithreading How do I share hash of hash of arrays
by BrowserUk (Patriarch) on Jan 24, 2015 at 13:59 UTC

    Hm. I only just now notice your silent update. That also .... rude.

    Ignoring lots of strange stuff in your code, like:

    sub initThreads{ my @initThreads; for(my $i = 1;$i<=$num_of_threads;$i++){ push(@initThreads,$i); } return @initThreads; } # use the initThreads subroutine to create an array of threads. my @threads = initThreads();

    Which does exactly the same as:my @threads = 1 .. $num_of_threads; but in an obscure and very costly way; and has absolutely nothing to do with threads -- it doesn't create threads; nor init threads; nor anything else to do with threads...

    C'est la vie. Pressing on.

    The problem: when you do this:

    $hash1{$affix}{$postfix} = threads::shared::shared_clone([$affix1]); +This is where the problem is. How can I assign an array to a hash of +hash

    You get: Thread 1 terminated abnormally: Invalid value for shared scalar..

    The problem is that whilst my %hash1 :shared; is shared, the nested hash required by

    $hash1{ $affix } { $postfix } = ...; #................^^^^^^^^^^^^

    Is being autovivified; and is therefore not shared. So, to assign that you need to do:

    $hash1{ $affix } = &share( {} ); ## Add an empty shared hash ## THEN you can do $hash1{ $affix }{ $postfix } = ....

    But, the end of that line is also weird:

    ..................... threads::shared::shared_clone( [ $affix1 ] );

    You are taking a simple scalar, making an unshared, single entry array from it, then cloning that into a shared, single entry array.

    Are you sure you need an array here?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
    In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
A reply falls below the community's threshold of quality. You may see it by logging in.