Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: Printing to STDERR causes deadlocks.

by bmann (Priest)
on Apr 26, 2005 at 20:52 UTC ( [id://451764]=note: print w/replies, xml ) Need Help??


in reply to Printing to STDERR causes deadlocks.

It hangs almost every time for me, with or without TRACE (1.8G Pentium IV, Win2K, Perl 5.8.4).

It looks like a race condition. If the the GetData thread sets $$doneRef in the space after while ( !$done ) is evaluated, the lock on $sharedData will block and wait for a signal indefinitely.

Since these threads are in lock-step, it seems to me a simple threads->yield near the end of the main thread's while loop (or even a short sleep before the loop starts) would force the GetData thread to start first, thereby preventing the race condition from happening. Should the code get more complex and longer running, all bets would be off - it would be very difficult to prove there wouldn't be a race condition.

Have you considered using threads::shared::semaphore instead?

Update: I added sleep 1; before the loop in GetDataT, results are the loop hangs every time. Added threads->yield; before the closing brace of the main thread's while loop, succeeded every time - even with the sleep. Even though it appears to work, yield is only a suggestion to the OS, not a guarantee.

Replies are listed 'Best First'.
Re^2: Printing to STDERR causes deadlocks.
by BrowserUk (Patriarch) on Apr 26, 2005 at 21:08 UTC

    Yes. I've been through a gamut of variations using yield() and sleeps. The problem, besides that using either renders the communications so slow as to totally invalidate any benefits from the threading, is that as soon as you move the code to a multi-processor system, you are into a completely different set of dynamics and need to start again.

    This should not be necessary. It certainly isn't needed if you use the native threading facilities provided by my OS.

    Have you considered using threads::shared::semaphore instead?

    Have you looked at what Thread::Semaphore actually does?


    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?
      I agree that yield and sleep won't solve it reliably - actually, I indicated that in my previous node.

      The problem is the space between signaling the main thread and setting eof and the space between testing whether eof is true and waiting on the shared variable. One of these actions needs to be atomic - you don't want to wait for more data if eof is true.

      How about this - replace getDataT with this, it'll set $done then signal $sharedData is ready, removing the race condition:

      sub getDataT { my ( $handle, $sharedDataRef, $doneRef ) = @_; my $temp; while( !$$doneRef ) { warn "t-Locking" . $/; lock $$sharedDataRef; warn 't-Waiting' . $/; cond_wait( $$sharedDataRef ) while $$sharedDataRef; warn 't-Setting' . $/; $$sharedDataRef = $handle->getline; # set $done before handing the data over to the main thread $$doneRef = 1 if $handle->eof; warn 't-Signalling' . $/; cond_signal( $$sharedDataRef ); } return; }
      I would expect that to scale gracefully.

      Have you looked at what Thread::Semaphore actually does?
      Just the docs. Now I have read the source... point taken ;)

        It still hangs when tracing is enabled, except now it hangs every time (20 attempts). I've posted the modified code below in case I screwed something up? (I assumed the my $temp; was an artifact?)

        I'd tried several variations on this theme also without success.

        I've also tried using locking directly on $done and $$doneRef, more out of desperation than logic, but it made no difference.


        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?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://451764]
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-03-29 15:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found