A loop in a thread... very greedy

need a class(we’ll call it a ‘simulator’ since that’s what i’m
attempting to write) to run a loop.
need that loop to stop when asked to, such as when the user that started
it clicks a button to stop it.

i write java that does this sort of thing all the time.
HOWEVER, when i try it in ruby, only bad things happen.

check this out:

start r.rb
class Simulator
attr_accessor :running
attr_accessor :sim_thread
def start
running = true;
puts “starting simulator…”
sim_thread= Thread.new(){
puts “sim thread started”
while(running)
300000.times do |x|
x+=1
end
puts ‘did a buncha stuff a simulator might do’
Thread.pass
end
puts “sim thread stopped”
}
sim_thread.join
sim_thread
end
def stop
puts “stopping simulator…”
running = false
end
end
Thread.abort_on_exception = true
simulator = Simulator.new
thread = simulator.start
puts “started simulator, now we stop it…”
simulator.stop
end r.rb

i get no exceptions in the thread.
the output:
starting simulator…
sim thread started
did a buncha stuff a simulator might do
did a buncha stuff a simulator might do
did a buncha stuff a simulator might do

this line never executes:

puts “started simulator, now we stop it…”

why does ruby not leave the thread lone to do its thing,
and do other things ?

instead, it seems to get stuck in the while loop, as if i didn’t put it
in a separate thread.

any help much appreciated, thanks.

On Dec 30, 2007, at 10:52 PM, Abraham Tio wrote:

sim_thread.join

You’re explicitly asking the main thread to let
the sim_thread run to completion. Don’t join
with another thread if you don’t want to wait
for it to exit.

Gary W.

why does ruby not leave the thread lone to do its thing,
and do other things ?
it does … usually, but since you’re explicitly joining it, it’ll wait
in start method untill thread finishes

instead, it seems to get stuck in the while loop, as if i didn’t put it
in a separate thread.
You did, and then you turned multi threaded application into single
threaded one

any help much appreciated, thanks.
remove join. read documentation (as java user you should be used to it)

On Dec 30, 2007, at 7:52 PM, Abraham Tio wrote:

Thread.abort_on_exception = true
simulator = Simulator.new
thread = simulator.start
puts “started simulator, now we stop it…”
simulator.stop

Others have pointed out not to use join. Of course, once you remove
join, the start and stop methods are invoked one right after another,
so you must put a sleep(n) between the two to observe the child thread
running independent of the main thread.

On Dec 30, 2007, at 7:52 PM, Abraham Tio wrote:

start r.rb
class Simulator
attr_accessor :running
attr_accessor :sim_thread
def start
running = true

   self.running = true
 end
 puts "sim thread stopped"

}
sim_thread.join
sim_thread
end
def stop
puts “stopping simulator…”
running = false

   self.running = false

end
end
Thread.abort_on_exception = true
simulator = Simulator.new
thread = simulator.start
puts “started simulator, now we stop it…”
simulator.stop
end r.rb

You have an attr_accessor :running but you were assigning to a
running local variable. You need to either use @running = true or
self.running = true> When ruby sees ‘running = true’ it decides that
running is a local variable, so using running = does not set the
@running ivar via the attr_acessor but self.running = true does.

Cheers-

Abraham Tio wrote:

need a class(we’ll call it a ‘simulator’ since that’s what i’m
attempting to write) to run a loop.
need that loop to stop when asked to, such as when the user that started
it clicks a button to stop it.

i write java that does this sort of thing all the time.
HOWEVER, when i try it in ruby, only bad things happen.

check this out:

here a woking code

class Simulator
attr_accessor :running
attr_accessor :sim_thread
def start
@running = true; #instance var
puts “starting simulator…”
@sim_thread= Thread.new(){ #instance var
puts “sim thread started”
while(@running)
300000.times do |x|
x+=1
end
puts ‘did a buncha stuff a simulator might do’
Thread.pass
end
puts “sim thread stopped”
}
# @sim_thread.join no join
@sim_thread
end
def stop
puts “stopping simulator…”
@running = false
end
end
Thread.abort_on_exception = true
simulator = Simulator.new
thread = simulator.start
puts “started simulator, now we stop it…”
simulator.stop

wait simulator end

simulator.sim_thread.join

Enjoy!