a loop in a thread... very greedy

A

Abraham Tio

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

Gary Wright

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 Wright
 
M

Marcin Raczkowski

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)
 
S

s.ross

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

Ezra Zygmuntowicz

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
-- (e-mail address removed)
-- EngineYard.com
 
T

Tiziano Merzi

Abraham said:
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!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top