Threads issue

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.

Marcin T. 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 B. wrote:

Marcin T. 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).

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

Preaty good experience, isn’t it? I know what is going on! :slight_smile:
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.

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.erikveen.dds.nl/tmp/code1.trace.png
http://www.erikveen.dds.nl/tmp/code2.trace.png

gegroet,
Erik V. - http://www.erikveen.dds.nl/