Threads and Deadlocks

M

Mc Osten

It seems that the standard ruby interpreter is able to detect deadlocks
(at least it detects when all threads are deadlocked).

In this case it terminates. It appears it doesn't do throwing an
exception...

Where can I find more infos about this? Can I insert into this and break
the deadlock in a (hopefully) softer way (I could know a specific thread
*can* be terminated).

Where can I find some infos about the deadlock revelation algorithms it
uses and such? This is just part of the "default" ruby interpreter or it
is defined in ruby itself?

Moreover how are regarded threads in the Ruby community? When I use
Python it's usually not advised and it is encouraged to move to an
asynchronous model (Twisted).

Thanks in advance.
 
E

Eric Hodel

It seems that the standard ruby interpreter is able to detect
deadlocks (at least it detects when all threads are deadlocked).

In this case it terminates. It appears it doesn't do throwing an
exception...

There's nowhere to throw an exception to, all threads are blocked
from running.
Where can I find more infos about this? Can I insert into this and
break the deadlock in a (hopefully) softer way (I could know a
specific thread *can* be terminated).

No. The error is in your programming. Terminating a thread won't
break the deadlock because either it is holding a resource other
threads are waiting on or it is waiting on a resource some other
thread is using and sleeping.
Where can I find some infos about the deadlock revelation
algorithms it uses and such? This is just part of the "default"
ruby interpreter or it is defined in ruby itself?

It is part of the interpreter and written in C.
Moreover how are regarded threads in the Ruby community? When I use
Python it's usually not advised and it is encouraged to move to an
asynchronous model (Twisted).

Everybody uses threads in Ruby.
 
M

Mc Osten

Eric Hodel ha scritto:
There's nowhere to throw an exception to, all threads are blocked from
running.

What happens then? Is there any documentation about this (I'd rather not
to read directly the source, but if there is no other way...)
No. The error is in your programming. Terminating a thread won't break
the deadlock because either it is holding a resource other threads are
waiting on or it is waiting on a resource some other thread is using and
sleeping.

No. The error is not in my programming since this is no real case.

The deadlock is intentionally created in the most obvious way just to
see what happened; in this sense the program is correct, it does exaclty
what it was meant to: it deadlocks.

If I can somehow trap the event that makes the ruby interpreter
terminate I could obviously recover the deadlock, since blocked
resources would have been constructed to be recoverable.

Probably I am not able to explain what I'm looking for: this is not real
case programming. This are kind of teaching examples.
It is part of the interpreter and written in C.

So I can't assume JRuby (for example) will act the same, can I?
Everybody uses threads in Ruby.

Ok.
 
R

Robert Klemme

Mc Osten said:
Eric Hodel ha scritto:


What happens then? Is there any documentation about this (I'd rather
not to read directly the source, but if there is no other way...)

I did some experimenting with the attached script. The trace actually seems
to show a "raise" but none of the exception blocks catches anything.
"ensure" is executed nevertheless. This is strange. Another strange thing
is that "raise" does not show up if you uncomment those two lines that print
the thread ids.
If I can somehow trap the event that makes the ruby interpreter
terminate I could obviously recover the deadlock, since blocked
resources would have been constructed to be recoverable.

It is generally the better approach to avoid deadlocks programmatically.
Probably I am not able to explain what I'm looking for: this is not
real case programming. This are kind of teaching examples.


So I can't assume JRuby (for example) will act the same, can I?

For these low level things you should not rely on similar behavior. And you
also should not rely on deadlock detection. I guess the interpreter uses
some kind of special mechanism. If you want to know what exactly happens
here a look into the source code is probably the best.

Kind regards

robert
 
M

Mc Osten

I did some experimenting with the attached script.

Thank you very much.
The trace actually seems
to show a "raise" but none of the exception blocks catches anything.

Yes. I tried to with a generic rescue clause and it did not catch.
"ensure" is executed nevertheless. This is strange. Another strange thing
is that "raise" does not show up if you uncomment those two lines that print
the thread ids.

I have no clues about it...
For these low level things you should not rely on similar behavior.

Ok. In fact I'm not suprised.
 
N

nobu

Hi,

At Sat, 11 Mar 2006 23:53:43 +0900,
Mc Osten wrote in [ruby-talk:183655]:
It seems that the standard ruby interpreter is able to detect deadlocks
(at least it detects when all threads are deadlocked).

In this case it terminates. It appears it doesn't do throwing an
exception...

ThreadError will be raised in the main thread.

$ ruby -e 'begin Thread.start{Thread.main.join}.join; rescue ThreadError => e; p e; end'
#<ThreadError: Thread#join: deadlock 0xb7df6824 - mutual join(0xb7de9368)>
 
R

Robert Klemme

Hi,

At Sat, 11 Mar 2006 23:53:43 +0900,
Mc Osten wrote in [ruby-talk:183655]:
It seems that the standard ruby interpreter is able to detect
deadlocks (at least it detects when all threads are deadlocked).

In this case it terminates. It appears it doesn't do throwing an
exception...

ThreadError will be raised in the main thread.

$ ruby -e 'begin Thread.start{Thread.main.join}.join; rescue
ThreadError => e; p e; end' #<ThreadError: Thread#join: deadlock
0xb7df6824 - mutual join(0xb7de9368)>

Hm, but why then isn't it caught by a clause "rescue Exception => e"?

Wondering...

robert
 
M

Mc Osten

Hm, but why then isn't it caught by a clause "rescue Exception => e"?

For example in this program, no exception is caught:

require "thread"

m1 = Mutex.new
m2 = Mutex.new

begin

p "begin"
t1 = Thread.new do
m1.lock;
sleep rand ;
begin
m2.lock
rescue ThreadError => e;
print "Rescuing t1"
end
end

t2 = Thread.new do
m2.lock;
sleep rand ;
begin
m1.lock
rescue ThreadError => e;
print "Rescuing t2"
end
end

p "joining..."
t1.join
t2.join

rescue ThreadError => e;
print "Rescuing..."
end
 
C

Charles O Nutter

------=_Part_594_17454976.1142454744155
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

JRuby currently uses Java threads to implement Ruby threads, and therefore
the only deadlock detection available is that provided by Java. However, if
you have threads deadlocking it is, as others have said, an issue with your
code that should be corrected. Ruby makes an assumption that the threads
will never wake up (or perhaps knows they will never wake up because of
circular dependencies) and chooses to kill them. In Java, you're perfectly
welcome to create deadlocked threads and Java will allow you to deadlock if
that's how you choose to write your code. Either way, if you have deadlocks=
,
you need to correct that in your code rather than expecting the interpreter
to save you.

So I can't assume JRuby (for example) will act the same, can I?


--
Charles Oliver Nutter @ headius.blogspot.com
JRuby Developer @ jruby.sourceforge.net
Application Architect @ www.ventera.com

------=_Part_594_17454976.1142454744155--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top