[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Threads issue.

Marcin Tyman

6/29/2007 6:28:00 PM

Hi guys,
Here is my program:
------------------------------------------------------------------------------
def my()
i=0

while i<100
i+=1
puts "Into my: #{Thread.current}"
Thread.stop if i == 40
end
end


myThread = Thread.new {
puts "Into thread: #{Thread.current}"
#Thread.stop
my()
}

i=0
while i<10
i+=1
puts "Main thread: #{Thread.current}"
end

puts "myThread is not alive" if !myThread.alive?
Thread.pass #####################################here is my
issue!!!!
myThread.run
myThread.join()
---------------------------------------------------------------------------

I cannot understand why this program cannot run without Thread.pass
line. Without the line following message appeard:

deadlock 0x283fef8: sleep:- - c:/Documents and Settings/Marcin/Moje
dokumenty/P
roximetry/Ruby/Threads2/threads2.rb:7
deadlock 0x284c748: sleep:J(0x283fef8) (main) - c:/Documents and
Settings/Marcin
/Moje dokumenty/Proximetry/Ruby/Threads2/threads2.rb:27
c:/Documents and Settings/Marcin/Moje
dokumenty/Proximetry/Ruby/Threads2/threads
2.rb:27:in `join': Thread(0x284c748): deadlock (fatal)
from c:/Documents and Settings/Marcin/Moje
dokumenty/Proximetry/Ruby/Thr
eads2/threads2.rb:27

I have lack of knowledge in programming threads but I supposed that
myThread.run should starts stopped thread before myThread.join. Did I
forget about something?

I will be appreciated for any help
Thanks in advance.

--
Posted via http://www.ruby-....

5 Answers

Lionel Bouton

6/29/2007 7:20:00 PM

0

Marcin Tyman wrote:
> Hi guys,
> Here is my program:
> ------------------------------------------------------------------------------
> def my()
> i=0
>
> while i<100
> i+=1
> puts "Into my: #{Thread.current}"
> Thread.stop if i == 40
> end
> end
>
>
> myThread = Thread.new {
> puts "Into thread: #{Thread.current}"
> #Thread.stop
> my()
> }
>
> i=0
> while i<10
> i+=1
> puts "Main thread: #{Thread.current}"
> end
>
> puts "myThread is not alive" if !myThread.alive?
> Thread.pass #####################################here is my
> issue!!!!
> myThread.run
>

Only an educated guess :
myThread may not have stopped yet here. Strictly speaking, even
Thread.pass can not guarantee it because the scheduler could decide to
pass the control back to the "primary" thread before i == 40 in my().
If you get a deadlock it probably means that Thread#run cannot be called
on an already running Thread (which isn't really surprising but if true
should be mentionned in its documentation).

If it works with either Thread.pass or Thread.stop in the Thread.new
block uncommented my guess could very well be the actual source of your
problem.

Lionel

Marcin Tyman

6/29/2007 7:43:00 PM

0

Lionel Bouton wrote:
> Marcin Tyman wrote:
>> end
>> while i<10
>> i+=1
>> puts "Main thread: #{Thread.current}"
>> end
>>
>> puts "myThread is not alive" if !myThread.alive?
>> Thread.pass #####################################here is my
>> issue!!!!
>> myThread.run
>>
>
> Only an educated guess :
> myThread may not have stopped yet here. Strictly speaking, even
> Thread.pass can not guarantee it because the scheduler could decide to
> pass the control back to the "primary" thread before i == 40 in my().
> If you get a deadlock it probably means that Thread#run cannot be called
> on an already running Thread (which isn't really surprising but if true
> should be mentionned in its documentation).
>
> If it works with either Thread.pass or Thread.stop in the Thread.new
> block uncommented my guess could very well be the actual source of your
> problem.
>
> Lionel

Lionel,
It looks like the issue is in Thread#run which doesn't guarantee
starting myThread before Thread#join. If i.e. myThread.pass is commented
out and any time consuming loop is included before myThread.run
everything works fine (without Thread#pass).

--
Posted via http://www.ruby-....

Lionel Bouton

6/29/2007 7:57:00 PM

0

Marcin Tyman wrote:
> Lionel,
> It looks like the issue is in Thread#run which doesn't guarantee
> starting myThread before Thread#join. If i.e. myThread.pass is commented
> out and any time consuming loop

In the primary Thread I suppose?

> is included before myThread.run
> everything works fine (without Thread#pass).
>
>

Which means you let myThread stop before running myThread.run, doesn't it?

Does the rubydoc example for Thread.stop:

a = Thread.new { print "a"; Thread.stop; print "c" }
Thread.pass
print "b"
a.run
a.join


at least outputs 'abc' for you ?

Lionel

Marcin Tyman

6/29/2007 8:59:00 PM

0

Preaty good experience, isn't it? I know what is going on! :-)
Thread#run in main thread is invoked earlier than myThread is stopped.
myThread is stopped when the main thread is fineshed (so after
myThread.run statement). That is why Thread#join returns exception (dead
lock) becouse myThread stops when condition in while in my() function is
true.

Thanks for help. Now everything is clear.


--
Posted via http://www.ruby-....

Erik Veenstra

6/30/2007 8:41:00 AM

0

Joining a stopped thread causes a deadlock.

Consider this deadlocking code:

Thread.fork do
Thread.stop
end.join

On the other hand, the following code does work:

Thread.fork do
Thread.stop
end.run.join

To prove that Thread.stop was really executed, I ran both
scripts with a trace:

http://www.erikve...tmp/code1...
http://www.erikve...tmp/code2...

gegroet,
Erik V. - http://www.erikve...