Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: threads::shared - when to lock a hash ?

by zwon (Abbot)
on Oct 16, 2011 at 07:45 UTC ( [id://931740]=note: print w/replies, xml ) Need Help??


in reply to threads::shared - when to lock a hash ?

Then, if you have one write and multiple reads to a single scalar, it seems you do not need locking either. Each read either gets the value before the write, or the one after, but not something else. Correct?

No, not correct, you can get inconsistent value in the reading thread. You always have to lock shared variable when you accessing it.

  • Comment on Re: threads::shared - when to lock a hash ?

Replies are listed 'Best First'.
Re^2: threads::shared - when to lock a hash ?
by dave_the_m (Monsignor) on Oct 16, 2011 at 09:30 UTC
    You always have to lock shared variable when you accessing it
    Wrong. Perl internally locks the variable before reading from or writing to it, so you don't need to lock it to avoid a corrupted value.

    As to the OP's questions: R1 is safe, while R2 behaves like R3: i.e. it iterates over the hash pushing individual values onto @x. In R3, if another thread is adding or deleting elements, or also iterating, then it will affect the result in the same way as if a single thread was doing it, e.g.

    while (($k, $v) = each(%h)) { # stuff here which adds or deletes elements, # or uses each/keys/values }
    W1,2,3 are all safe.

    Of course in all the above, "safe" means "not corrupting perl's internal state"; perl's internal locking causes all the reads and writes to be serialised. You may of course still need to do locking at a higher level to ensure the safety of your own code's logic

    Dave.

      Perl internally locks the variable before reading from or writing to it

      Thanks, I should have thought that perl somehow protects its internal state. I couldn't find anything in threads::shared manual, so I looked into source and what I understand is that perl locks not just variable but the whole shared space, is it correct?

        perl locks not just variable but the whole shared space, is it correct?
        Yes.

        All shared variables are kept in a separate interpreter, with stub copies of the variable in each thread, and a tieing mechanism used to access the vars. So when you do something like $shared_var = 1, your thread notes that $shared_var is tied, an calls the STORE method (which happens to be implemented in XS for efficiency). This method sets a global lock and copies the new value to the 'real' variable.

        Dave.

      so you don't need to lock it to avoid a corrupted value.

      It's possible that the ops return junk if all the lock does is avoid corruption. I'm not sure this answers anything.

      For starters, does a hash have one iterator per thread or just one iterator? each and possibly keys aren't safe if it's the latter.

        The ops never return junk; they will return values consistent with whatever thread did the most recent update. For example, this will never die:
        use threads; use threads::shared; my $x : shared; for (0..9) { threads->new(sub { while (1) { $x = $_[0]; die unless $x =~ /^\d$/; } }, $_ ); } sleep;
        There is one iterator per shared object, which is why I mentioned earlier that if other threads do each/keys/value too, it will affect the result

        Dave.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://931740]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (4)
As of 2024-04-25 07:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found