[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

threads output/execution question

Mr_Tibs

5/8/2007 2:14:00 AM

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

2 Answers

Robert Klemme

5/8/2007 9:31:00 AM

0

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

Mr_Tibs

5/8/2007 7:44:00 PM

0

Hi Robert,

Thanks so much for your answer. Actually even with your code I had the
same problem. If I would wait for more than 5 seconds, the worker
thread would not print "Job.finish" (Job.finish would be printed after
my subsequent input). I realized in both cases that the line "while
option = gets" was blocking the thread from outputing.

Tiberiu