From: Robert Klemme Date: 2007-05-08T18:35:11+09:00 Subject: Re: threads output/execution question 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