Robert Klemme
5/8/2007 9:31:00 AM
On 08.05.2007 04:14, tiberiu.motoc@gmail.com wrote:
> Hi,
>
> I have a ruby multi-threaded application and I don't understand its
> behaviour. I hate just dumping code in a post and asking questions,
> but I cannot explain the problem otherwise. In the code below, I have
> a loop which requests user input to either start/stop a job. The
> execution of the job will happen in a separate thread, because the job
> can terminate unexpectedly. What I don't understand in the code, is
> why doesn't the application just print "Job.start" and
> "'DummyThreads.start" after 5 seconds in the same standard output
> screen (as where it is receiving input). It is not even about the
> screen (I tried putting STDOUT.flush after every puts statement), the
> code is not even executed until I subsequently call DummyThreads
> again.
>
> So, what I get is:
> Enter option: 1
> [...more than 5 seconds passed...]
> Enter option: 1
> [...immediately...]
> Job.start
> DummyThreads.start
> Enter option:
> [...]
>
> What I expected is:
> Enter option: 1
> Enter option:
> [...after 5 seconds...]
> Job.start
> DummyThreads.start
> [...]
>
> Thanks,
> Tiberiu
>
> PS. here is my code
>
> class Job
> def run
> sleep 5
> puts 'Job.start'
> end
> def kill
> sleep 5
> puts 'Job.stop'
> end
> end
>
> class DummyThreads
> def initialize
> @job = Job.new
> end
> def start
> t = Thread.new { @job.run; puts 'DummyThreads.start' }
> t.join
> end
> def stop
> t = Thread.new { @job.kill; puts 'DummyThreads.stop' }
> t.join
> end
> end
>
> # create DummyThreads
> dummythreads = DummyThreads.new
>
> # get user input
> puts 'Enter option: '
> STDOUT.flush
> while option = gets
> case option.to_i
> when 1: t = Thread.new { dummythreads.start }
> when 2: t = Thread.new { dummythreads.stop }
> when 0: break
> end
> puts 'Enter option: '
> STDOUT.flush
> end
>
IMHO you have too many threads in there. Try this for an alternative:
robert
class Job
class JobTermination < Exception; end
def run
@thread = Thread.current
begin
puts 'Job.start'
work
puts 'Job.finish'
rescue JobTermination
puts 'Job.killed'
ensure
@thread = nil
end
end
def kill
puts 'Job.stop'
@thread.raise JobTermination if @thread
end
private
def work
sleep 5
end
end
class DummyThreads
def initialize
@job = Job.new
end
def start
puts 'DummyThreads.start'
Thread.new { @job.run }
end
def stop
@job.kill
puts 'DummyThreads.stop'
end
end
# create DummyThreads
dummythreads = DummyThreads.new
# get user input
puts 'Enter option: '
STDOUT.flush
while option = gets
case option.to_i
when 1: dummythreads.start
when 2: dummythreads.stop
when 0: break
end
puts 'Enter option: '
STDOUT.flush
end