Forum: Ruby Threads and Deadlocks

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
10ac092ffea69dbf830f7159b05dfc77?d=identicon&s=25 Mc Osten (Guest)
on 2006-03-11 15:54
(Received via mailing list)
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.
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-03-11 17:03
(Received via mailing list)
On Mar 11, 2006, at 8:53 AM, Mc Osten wrote:

> 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.

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
10ac092ffea69dbf830f7159b05dfc77?d=identicon&s=25 Mc Osten (Guest)
on 2006-03-11 17:46
(Received via mailing list)
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.
5befe95e6648daec3dd5728cd36602d0?d=identicon&s=25 Robert Klemme (Guest)
on 2006-03-11 19:00
(Received via mailing list)
Mc Osten <riko@despammed.com> wrote:
> 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...)

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.
>
>> It is part of the interpreter and written in C.
>
> 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
10ac092ffea69dbf830f7159b05dfc77?d=identicon&s=25 Mc Osten (Guest)
on 2006-03-13 02:10
(Received via mailing list)
On Sat, 11 Mar 2006 18:53:29 +0100, Robert Klemme wrote:

> 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.
F1d6cc2b735bfd82c8773172da2aeab9?d=identicon&s=25 unknown (Guest)
on 2006-03-13 15:08
(Received via mailing list)
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)>
5befe95e6648daec3dd5728cd36602d0?d=identicon&s=25 Robert Klemme (Guest)
on 2006-03-13 17:39
(Received via mailing list)
nobu@ruby-lang.org wrote:
> 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
10ac092ffea69dbf830f7159b05dfc77?d=identicon&s=25 Mc Osten (Guest)
on 2006-03-13 22:02
(Received via mailing list)
On Mon, 13 Mar 2006 17:33:30 +0100, Robert Klemme wrote:

> 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
F1d37642fdaa1662ff46e4c65731e9ab?d=identicon&s=25 Charles O Nutter (Guest)
on 2006-03-15 21:33
(Received via mailing list)
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.
This topic is locked and can not be replied to.