gives the error: 'Invalid value for shared scalar '

lock(%cfg::thash); $v1="A"; $v2="1"; $cfg::thash{$v1}{$v2} ="b";

The problem is that this line of code:

$cfg::thash{$v1}{$v2} ="b";

is equivalent to

## Make the value of key 'A' an anonymous hash. $cfg::thash{A} = {}; ## add a key '1' to that anonymous hash with the value "b"; $cfg::thash{A}{1} = "b";

The thing with shared hashes (and shared arrays), is that everything you put into them also has to be shared.

What's more, you cannot share an array or hash that already has data in it. Or rather you can, but it will silently empty it in the process. This is (apparently) a deliberate design decision---and a bad one in my opinion as it makes using shared hashes and arrays almost impossible.

The basis of the decision (as it was explained to me) is that if adding elements to a shared hash automatically shared the things you put in it, then it would have to be a recursive process scanning through anything in the things you added sharing them. Ie. If you add a reference to an existing deeply nested datastructure (eg. a HoAoHoA...), then adding that reference to a shared hash, would require the entire nested structure to be traversed and all it's sub elements shared.

This was deemed likely to take too long. It was easier to issue an uninformative error message and force the user to do the traverse. Except of course, this kind of complex processing is difficult to get right, almost impossible in user space, and exactly the kind of thing that should be done by a piece of write-it-once, get-it-right-once, tight (XS) library code.

This is why I tend to avoid sharing compex datastructures in my threaded code. It renders autovivication impossible to use, which make using them messy and awkward.

Anyway, you can do what you are trying to do by sharing the intermediate elements individually and building the stricture up. However, due to the use (and limitations of) perl prototypes on the threads::shared::share() function, you cannot use it on anonymous hashes or arrays directly. Instead, you have to assign a ref to them to a temporary scalar and then apply share() to that.

This will do what you asked about:

use strict; use threads; use threads::shared; my %thash : shared; ## Share the base hash my $temp = {}; ## Get a reference to an anon. hash in a temp var share( $temp ); ## share() the temp var $thash{A} = $temp; ## assign it into the structure $thash{A}{1} = 'b'; ## At this point you have what you asked for.

Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

In reply to Re: Declaring/Assigning thread shared vars by BrowserUk
in thread Declaring/Assigning thread shared vars by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.