Thanks for fixing the code but I guess you are missing the point. My contention in an earlier message was that this piece of code by BrowserUk is not thread safe:

sub safe_set { my $k = shift; my $v :shared = shift; lock $$h{ $k }; $h{$k} = \$v; }

My reasoning of it was as follows:

TIMESTEP 0: Say, $h{$k} points to v1 Thread T0: Holding lock on v1 Thread T1: Waiting on Lock on v1 TIMESTEP 1: T0 changes $h{$k} = \$v2, releases lock on $v1 TIMESTAMP 2: (Thread T2 makes an entrance) Thread T2: Acquires Lock on v2, proceeds Thread T1: Acquires Lock on v1, proceeds <Race-around condition>

In other words, the problem with the above safe_set implementation is that it creates a new $v so threads could be waiting on different "copies" of $v, thereby causing a race condition.

To test out safe_set implementation, I made the hash %h to have a single key and tried updates using several threads. Notice that I copy and then add one to it. If there is a race condition the value of variable is surely affected. The code did not run at all and failed giving out a MUTEX_LOCK error: So, the real question here is if my testing code (given below) really points to a problem with the safe_set function. The way you have implemented it basically changes the flavor of safe_set, which of course runs.. I hope you are able to see my point here.

#! perl -slw use strict; use threads; use threads::shared; our %h : shared; # Setting up just a single row to increase chances # a race condition our $k = 'AAA'; our $val : shared = 0; our $THREADS = 50; our $iter = 50; $h{$k} = \$val; # Safe_set similar to BrowserUk sub safe_set { my $v :shared; # Critical Section { lock ${$h{$k}}; $v = ${$h{$k}} + 1; $h{$k} = \$v; } } # Keep locking to increment $$h{$k} sub test_safe_set { for (my $i = 0; $i < $iter; ++$i) { safe_set(); } } my @pool = map{ threads->create(\&test_safe_set) } 1 .. $THREADS; $_->join for @pool; warn ${$h{$k}}, "failed\n" if ${$h{$k}} != $THREADS * $iter;

In reply to Re^6: Avoid Locking Entire Hashes by jagan_1234
in thread Avoid Locking Entire Hashes by jagan_1234

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.