# Re: Thread#stop

**URL:** <https://www.ruby-forum.com/t/re-thread-stop/68982>\
**Category:** Ruby\
**Created:** [February 16, 2006, 12:42am UTC](https://www.ruby-forum.com/t/re-thread-stop/68982 "2006-02-16T00:42:44Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [February 16, 2006, 12:42am UTC](https://www.ruby-forum.com/t/re-thread-stop/68982/1 "2006-02-16T00:42:44Z")

</div>

The following probably contains world-destroying race-conditions, but it  
roughly works. Making it work properly is left as an exercise for the  
reader.

$stoppable = []  
$stop\_all = false

def stop\_all  
$stop\_all = true  
end

def start\_all  
$stop\_all = false  
$stoppable.each {|t| p “waking #{t}”; t.wakeup}  
end

set\_trace\_func proc { |event, file, line, id, binding, classname|  
if $stop\_all && $stoppable.include?(Thread.current)  
p “#{Thread.current} stopping”  
Thread.stop  
p “#{Thread.current} restarted”  
end  
}

$stoppable \<\< Thread.new {  
while sleep 1  
p “child is running”  
end  
}

p “started”  
sleep 5  
p “stopping all”  
stop\_all  
sleep 5  
p “starting all”  
start\_all  
sleep 5  
p “exiting”

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [February 16, 2006, 12:57am UTC](https://www.ruby-forum.com/t/re-thread-stop/68982/2 "2006-02-16T00:57:49Z")

</div>

Daniel S. wrote:

> The following probably contains world-destroying race-conditions, but it  
> roughly works. Making it work properly is left as an exercise for the  
> reader.

Nice, but I think set\_trace\_func is going to kill my app. Thanks anyway,  
though.

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [February 19, 2006, 1:00am UTC](https://www.ruby-forum.com/t/re-thread-stop/68982/3 "2006-02-19T01:00:32Z")

</div>

Daniel S. wrote:

> end  
> p “#{Thread.current} restarted”  
> sleep 5  
> p “stopping all”  
> stop\_all  
> sleep 5  
> p “starting all”  
> start\_all  
> sleep 5  
> p “exiting”

On second thought, this is actually just what I need, with a small  
modification: only call set\_trace\_func when the request to stop comes  
in, and then call set\_trace\_func(nil) when threads are restarted.

For example:

th = Thread.new do  
loop do  
sleep 0.1  
puts “alive!”  
end  
end

sleep 0.3

puts “stopping”  
stopper = proc {|event, file, line, id, binding, classname|  
Thread.stop if Thread.current == th  
}  
set\_trace\_func stopper

sleep 1

puts “starting”  
set\_trace\_func nil  
th.wakeup

sleep 0.3

The output is:

alive!  
alive!  
stopping  
starting  
alive!  
alive!  
alive!

(There’s about a 1 sec delay between the “stopping” and “starting”  
lines, as desired.)

So, thanks for the suggestion, Daniel. I just didn’t consider it closely  
enough before, because I was scared away by set\_trace\_func.

---

<div class="post-metadata">

**Author:** ![dasch](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b2d939/32.png) [@dasch](https://www.ruby-forum.com/u/dasch)\
**Post date:** [February 19, 2006, 1:18am UTC](https://www.ruby-forum.com/t/re-thread-stop/68982/4 "2006-02-19T01:18:40Z")

</div>

And with a little extra work, one can use this to approximate  
Thread#backtrace as well as Thread#stop (neither of which exist):

th = Thread.new do  
loop do  
sleep 0.1  
puts “alive!”  
end  
end

sleep 0.3

puts “stopping”  
stopper = proc {|event, file, line, id, binding, classname|  
if Thread.current == th  
puts caller.join("\n from ")  
Thread.stop  
end  
}  
set\_trace\_func stopper

sleep 1

puts “starting”  
set\_trace\_func nil  
th.wakeup

sleep 0.3

alive!  
alive!  
stopping  
thread-stop.rb:6  
from thread-stop.rb:6  
from thread-stop.rb:4  
from thread-stop.rb:3  
starting  
alive!  
alive!  
alive!

(This is only approximate because the thread isn’t stopped until after  
the interpreter finishes whatever current ruby primitive is evaluating,  
but it’s good enough for my purposes.)
