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.
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!