# Raise problem in Thread

**URL:** <https://www.ruby-forum.com/t/raise-problem-in-thread/106240>\
**Category:** Ruby\
**Created:** [June 7, 2007, 8:04pm UTC](https://www.ruby-forum.com/t/raise-problem-in-thread/106240 "2007-06-07T20:04:38Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![oliver](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/85f322/32.png) [@oliver](https://www.ruby-forum.com/u/oliver)\
**Post date:** [June 7, 2007, 8:04pm UTC](https://www.ruby-forum.com/t/raise-problem-in-thread/106240/1 "2007-06-07T20:04:38Z")

</div>

Define following class:  
class MyThread \< Thread  
def initialize()  
super{  
puts “started”  
sleep 1000  
}  
end

def test\_raise()  
raise StandardError.new()  
puts “hello”  
end  
end

Open irb and run:  
irb(main):082:0\> thread = MyThread.new  
started=\> #\<MyThread:0xb7cec234 run\>  
irb(main):093:0\> thread.test\_raise  
hello  
=\> nil

I think the line “puts “hello”” should not be run after raising an  
exception.  
What is the reason of this problem?

Thanks.

---

<div class="post-metadata">

**Author:** ![oliver](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/85f322/32.png) [@oliver](https://www.ruby-forum.com/u/oliver)\
**Post date:** [June 7, 2007, 8:23pm UTC](https://www.ruby-forum.com/t/raise-problem-in-thread/106240/2 "2007-06-07T20:23:16Z")

</div>

oliver wrote:

> ```
> raise StandardError.new()
> 
> ```
> 
> I think the line “puts “hello”” should not be run after raising an  
> exception.  
> What is the reason of this problem?

The problem is that test\_raise is executed not by the MyThread thread,  
but by the main thread. The MyThread instance receives the exception and  
dies (silently because abort\_on\_exception is off), and the main thread  
continues executing the puts “hello”.

Keep in mind that the following contexts are different:

(1) _self_, the object that receives a message and performs the lookup  
to determine which method handles the message

(2) Thread.current: the thread that the interpreter is currently running  
to execute a method

Let’s look at the context when you call test\_raise. Even though the  
_self_ is your MyThread instance, the current thread is still the main  
thread.

If you want to send commands to a thread and have them executed _by_ the  
thread, you might want to set up a Queue that it reads.

Also, it’s useful to have the following when debugging threads:

Thread.abort\_on\_exception = true

(do this at the beginning of your program–you can also set this for  
individual threads, but the global setting is nice for debugging)

---

<div class="post-metadata">

**Author:** ![oliver](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/85f322/32.png) [@oliver](https://www.ruby-forum.com/u/oliver)\
**Post date:** [June 7, 2007, 8:36pm UTC](https://www.ruby-forum.com/t/raise-problem-in-thread/106240/3 "2007-06-07T20:36:17Z")

</div>

Joel VanderWerf wrote:

> If you want to send commands to a thread and have them executed _by_ the  
> thread, you might want to set up a Queue that it reads.

A queue is also much safer than Thread.raise, as was discussed on  
ruby-talk in the last few months, because raise can interrupt an ensure  
clause and result in cleanup not happening.

---

<div class="post-metadata">

**Author:** ![oliver](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/85f322/32.png) [@oliver](https://www.ruby-forum.com/u/oliver)\
**Post date:** [June 7, 2007, 8:53pm UTC](https://www.ruby-forum.com/t/raise-problem-in-thread/106240/4 "2007-06-07T20:53:55Z")

</div>

Hi Joel:

Thank you for your reply.

One thing I am a little confused is that the main thread continues  
executing the puts “hello”. From my point of view, puts “hello” is part  
of method test\_raise. So after the exception was raised and the MyThread  
instance was dead, the method should stopping running and just return  
nil to main thread. Why main thread need to continue running left part  
of this method? This can cause some unexpecting problems.

Thanks.

Joel VanderWerf wrote:

> oliver wrote:
> 
> > ```
> > raise StandardError.new()
> > 
> > ```
> > 
> > I think the line “puts “hello”” should not be run after raising an  
> > exception.  
> > What is the reason of this problem?
> 
> The problem is that test\_raise is executed not by the MyThread thread,  
> but by the main thread. The MyThread instance receives the exception and  
> dies (silently because abort\_on\_exception is off), and the main thread  
> continues executing the puts “hello”.
> 
> Keep in mind that the following contexts are different:
> 
> (1) _self_, the object that receives a message and performs the lookup  
> to determine which method handles the message
> 
> (2) Thread.current: the thread that the interpreter is currently running  
> to execute a method
> 
> Let’s look at the context when you call test\_raise. Even though the  
> _self_ is your MyThread instance, the current thread is still the main  
> thread.
> 
> If you want to send commands to a thread and have them executed _by_ the  
> thread, you might want to set up a Queue that it reads.
> 
> Also, it’s useful to have the following when debugging threads:
> 
> Thread.abort\_on\_exception = true
> 
> (do this at the beginning of your program–you can also set this for  
> individual threads, but the global setting is nice for debugging)

---

<div class="post-metadata">

**Author:** ![oliver](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/85f322/32.png) [@oliver](https://www.ruby-forum.com/u/oliver)\
**Post date:** [June 7, 2007, 9:27pm UTC](https://www.ruby-forum.com/t/raise-problem-in-thread/106240/5 "2007-06-07T21:27:24Z")

</div>

Oliver P. wrote:

> Hi Joel:
> 
> Thank you for your reply.
> 
> One thing I am a little confused is that the main thread continues  
> executing the puts “hello”. From my point of view, puts “hello” is part  
> of method test\_raise. So after the exception was raised and the MyThread  
> instance was dead, the method should stopping running and just return  
> nil to main thread. Why main thread need to continue running left part  
> of this method? This can cause some unexpecting problems.

Even if a thread is dead, it still responds to methods. It’s still an  
object, and all objects have a (private) #puts method that they inherit  
from Kernel.

This is actually very useful behavior:

th = Thread.new do  
1+2 # or some long computation  
end

sleep 0.1  
p th.alive? # ==\> false  
p th.value # ==\> 3

The thread is dead, but you can retrieve the result. (If you call  
Thread#value before the thread has finished, then it waits for it to  
finish.)

---

<div class="post-metadata">

**Author:** ![oliver](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/85f322/32.png) [@oliver](https://www.ruby-forum.com/u/oliver)\
**Post date:** [June 7, 2007, 9:31pm UTC](https://www.ruby-forum.com/t/raise-problem-in-thread/106240/6 "2007-06-07T21:31:26Z")

</div>

On 6/7/07, Oliver P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hi Joel:
> 
> Thank you for your reply.
> 
> One thing I am a little confused is that the main thread continues  
> executing the puts “hello”. From my point of view, puts “hello” is part  
> of method test\_raise. So after the exception was raised and the MyThread  
> instance was dead, the method should stopping running and just return  
> nil to main thread. Why main thread need to continue running left part  
> of this method? This can cause some unexpecting problems.

As Joel explained, the puts is runs on the current thread, but the  
exception is raised on the other thread. Just because some code is a  
method of a thread class doesn’t mean that it automatically runs on  
any particular thread.

Let’s try a little change to your code, change that puts “Hello” to  
puts “I am #{self}, current thread is #{Thread.current}”.

Now in irb:  
irb(main):013:0\> thread = MyThread.new  
started=\> #\<MyThread:0xb7b99a6c run\>  
irb(main):014:0\>  
thread.test\_raise  
I am #MyThread:0xb7b99a6c, current\_thread is #Thread:0xb7e087d0  
=\> nil  
irb(main):015:0\> Thread.current  
=\> #\<Thread:0xb7e087d0 run\>

Does that help?

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![oliver](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/85f322/32.png) [@oliver](https://www.ruby-forum.com/u/oliver)\
**Post date:** [June 7, 2007, 10:03pm UTC](https://www.ruby-forum.com/t/raise-problem-in-thread/106240/7 "2007-06-07T22:03:14Z")

</div>

Hi Rick:

Thank you for your reply.

So when we call raise method, we are calling the MyThread instance’s  
raise method and it stop running of MyThread instance. I tried to use  
Kernel.raise and Thread.current.raise. They all work fine and raise  
exception in main thread.

Thanks again.

Oliver

Rick Denatale wrote:

> On 6/7/07, Oliver P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Hi Joel:
> > 
> > Thank you for your reply.
> > 
> > One thing I am a little confused is that the main thread continues  
> > executing the puts “hello”. From my point of view, puts “hello” is part  
> > of method test\_raise. So after the exception was raised and the MyThread  
> > instance was dead, the method should stopping running and just return  
> > nil to main thread. Why main thread need to continue running left part  
> > of this method? This can cause some unexpecting problems.
> 
> As Joel explained, the puts is runs on the current thread, but the  
> exception is raised on the other thread. Just because some code is a  
> method of a thread class doesn’t mean that it automatically runs on  
> any particular thread.
> 
> Let’s try a little change to your code, change that puts “Hello” to  
> puts “I am #{self}, current thread is #{Thread.current}”.
> 
> Now in irb:  
> irb(main):013:0\> thread = MyThread.new  
> started=\> #\<MyThread:0xb7b99a6c run\>  
> irb(main):014:0\>  
> thread.test\_raise  
> I am #MyThread:0xb7b99a6c, current\_thread is #Thread:0xb7e087d0  
> =\> nil  
> irb(main):015:0\> Thread.current  
> =\> #\<Thread:0xb7e087d0 run\>
> 
> Does that help?
> 
> –  
> Rick DeNatale
> 
> My blog on Ruby  
> [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![oliver](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/85f322/32.png) [@oliver](https://www.ruby-forum.com/u/oliver)\
**Post date:** [June 7, 2007, 10:35pm UTC](https://www.ruby-forum.com/t/raise-problem-in-thread/106240/8 "2007-06-07T22:35:37Z")

</div>

On 07.06.2007 22:03, Oliver P. wrote:

> So when we call raise method, we are calling the MyThread instance’s  
> raise method and it stop running of MyThread instance. I tried to use  
> Kernel.raise and Thread.current.raise. They all work fine and raise  
> exception in main thread.

Basically whenever you invoke “raise” somewhere in code it’s really  
Kernel’s raise which delegates to Thread.current.raise. As you see,  
#raise is also an instance method of Thread so your situation was  
special because your class inherited Thread. That’s why the raise had a  
slightly different effect, namely raising the exception in that thread  
and not in the calling thread. Maybe this helps clarify:

irb(main):001:0\> Thread.current.methods.grep /raise/  
=\> [“raise”]  
irb(main):002:0\> Thread.instance\_methods.grep /raise/  
=\> [“raise”]  
irb(main):003:0\> method :raise  
=\> #\<Method: Object(Kernel)#raise\>  
irb(main):004:0\> Thread.current.method :raise  
=\> #\<Method: Thread#raise\>

It’s often confusing when first confronted with multithreading in OO  
languages like Ruby and Java: Thread’s are instances (i.e. objects) like  
all other objects but at the same time, there is a thread of execution  
(i.e. stack, program counter etc.) associated with them. But this  
relationship is not fixed: you can have Thread objects with no execution  
thread associated. In Java this is between creation of a Thread  
instance and invoking start() and after the thread terminated. In Ruby,  
since threads are started immediately, it’s only after a thread  
terminated.

Kind regards

robert
