Home > Archive > PERL Beginners > June 2007 > strange unexpected deadlock
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
strange unexpected deadlock
|
|
| Michael Scondo 2007-06-23, 7:58 am |
| Hi,
I'm trying to make myself familiar with threads.
However, I encountered some unexpected behaviour of locks/cond_wait I wasn't
able to figure out.
Could someone explain to me what's happening ??
Thanks, Michael
----------------------
#!/usr/bin/perl -w
use threads;
use threads::shared;
share( $x );
share( $y );
sub thread1{
print "1\n";
lock $x;
print "locked x: 1\n";
cond_wait $x;
print "thread1\n";
lock $y;
cond_signal $y;
print "t1\n";
}
sub thread2{
sleep 1;
lock $y;
# {
lock $x;
print "locked x: 2\n";
cond_signal $x;
# }
print "thread2\n";
sleep 1;
cond_wait $y;
print "t2\n";
}
my $t1 = threads->create( "thread1" );
my $t2 = threads->create( "thread2" );
$t1->join;
$t2->join;
print "exit.\n";
---------------------
I expected the script to have a output like:
---
1
locked x: 1
locked x: 2
thread2
thread1
t1
t2
exit.
---
Instead it hangs in the function thread1, at cond_wait $x,
so here's the actual output.
---
1
locked x: 1
locked x: 2
thread2
---
If I uncomment the two brackets of the function thread2, it works again. Which
I cannot understand.
---
sub thread2{
sleep 1;
lock $y;
{
lock $x;
print "locked x: 2\n";
cond_signal $x;
}
print "thread2\n";
sleep 1;
cond_wait $y;
print "t2\n";
}
| |
| Tom Phoenix 2007-06-23, 6:59 pm |
| On 6/23/07, Michael Scondo <michael.scondo@phil.stud.uni-erlangen.de> wrote:
> sub thread1{
> print "1\n";
> lock $x;
> print "locked x: 1\n";
> cond_wait $x;
Can't get past here until $x is signalled by another thread, and
unlocked by all other threads.
> print "thread1\n";
> lock $y;
> cond_signal $y;
> print "t1\n";
> }
>
> sub thread2{
> sleep 1;
> lock $y;
> # {
> lock $x;
> print "locked x: 2\n";
> cond_signal $x;
> # }
If the curly braces of that naked block were present, the lock on $x
would be released here, at the end of that scope. But it's still
locked, because cond_signal didn't unlock it either. (Did you think it
would?)
> print "thread2\n";
> sleep 1;
> cond_wait $y;
Can't get past here until $y is signalled by another thread, and
unlocked by all other threads.
> print "t2\n";
> }
As written, this is the end-of-scope for the lock on $x (as well as
the one on $y). But unless some third thread can rescue these first
two, they seem to be deadlocked, with the first waiting for $x to be
unlocked and the second waiting for $y to be signalled.
As you discovered, using the inner braces will release the lock on $x
soon enough to avoid the deadlock.
By the way, thanks greatly for the detailed, self-contained test case;
it showed exactly what you were doing.
Have fun with Perl!
--Tom Phoenix
Stonehenge Perl Training
| |
| Michael Scondo 2007-06-25, 7:59 am |
| On Saturday 23 June 2007 15:08, Tom Phoenix wrote:
> On 6/23/07, Michael Scondo <michael.scondo@phil.stud.uni-erlangen.de> wrote:
>
> Can't get past here until $x is signalled by another thread, and
> unlocked by all other threads.
>
> As written, this is the end-of-scope for the lock on $x (as well as
> the one on $y). But unless some third thread can rescue these first
> two, they seem to be deadlocked, with the first waiting for $x to be
> unlocked and the second waiting for $y to be signalled.
>
Thanks a lot for you explanation !
I didn't read the manual carefully enough....
Therefore I didn't realize that cond_wait locks a variable again AFTER it has
been signalled.
> As you discovered, using the inner braces will release the lock on $x
> soon enough to avoid the deadlock.
>
> By the way, thanks greatly for the detailed, self-contained test case;
> it showed exactly what you were doing.
>
DNRTFM
Did not read the XXXXing manual...
Thanks again for your help,
Michael
|
|
|
|
|