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.

···

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

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 Wright

···

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

    sim_thread.join

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)

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:

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

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

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

       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-
- Ezra Zygmuntowicz
-- Founder & Software Architect
-- ezra@engineyard.com
-- EngineYard.com

···

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

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!

···

--
Posted via http://www.ruby-forum.com/\.