Scheduler and thread

Hi
I want to make a scheduler like this.

module Timer
  def Timer.repeat_every(interval)
    Thread.new do
      loop do
        start_time = Time.now
        yield
        elapsed = Time.now - start_time
        sleep([interval - elapsed, 0].max)
      end
    end.join
  end
end

Timer.repeat_every(5) do
puts Time.now.to_i
end

puts "Doing other stuff..."

···

---------------------------------------------------
But it never prints out "Doing other stuff..."

How can I make it print out like
"Doing other stuff..."
1318284723
1318284728
1318284733

Thanks

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

Try this;

module Timer

   @timer = nil

   def Timer.repeat_every(interval)
     @timer = Thread.new do
       loop do
         start_time = Time.now
         yield
         elapsed = Time.now - start_time
         sleep([interval - elapsed, 0].max)
       end
     end
   end

   def Timer.stop
     unless @timer.nil?
       @timer.kill
       @timer.join(1) # don't hang forever
       @timer = nil
     end
   end

end

Timer.repeat_every(5) do
  puts Time.now.to_i
end

puts "Doing other stuff..."
sleep 10
puts "Stopping timer"
Timer.stop

As far as I can tell your execution is hanging on the join which will never return as the timer thread is in an infinite loop =]

Hope that helps
Sam

···

On 11/10/11 11:20, lover ruby wrote:

Hi
I want to make a scheduler like this.

module Timer
   def Timer.repeat_every(interval)
     Thread.new do
       loop do
         start_time = Time.now
         yield
         elapsed = Time.now - start_time
         sleep([interval - elapsed, 0].max)
       end
     end.join
   end
end

Timer.repeat_every(5) do
  puts Time.now.to_i
end

puts "Doing other stuff..."
---------------------------------------------------
But it never prints out "Doing other stuff..."

How can I make it print out like
"Doing other stuff..."
1318284723
1318284728
1318284733

Thanks

Thanks Robert. I use your Timer class in my program.

···

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

Sam Duncan wrote in post #1025958:

         sleep([interval - elapsed, 0].max)
---------------------------------------------------
But it never prints out "Doing other stuff..."

How can I make it print out like
"Doing other stuff..."
1318284723
1318284728
1318284733

Thanks

Try this;

module Timer

   @timer = nil

   def Timer.repeat_every(interval)
     @timer = Thread.new do
       loop do
         start_time = Time.now
         yield
         elapsed = Time.now - start_time
         sleep([interval - elapsed, 0].max)
       end
     end
   end

   def Timer.stop
     unless @timer.nil?
       @timer.kill
       @timer.join(1) # don't hang forever
       @timer = nil
     end
   end

end

Timer.repeat_every(5) do
  puts Time.now.to_i
end

puts "Doing other stuff..."
sleep 10
puts "Stopping timer"
Timer.stop

As far as I can tell your execution is hanging on the join which will
never return as the timer thread is in an infinite loop =]

Hope that helps
Sam

Thanks for help.
The result is
1318313034Doing other stuff...

1318313039

And stop. Even I remove Timer.stop.

I want something like UI.start_timer in Google sketchup. After
UI.start_timer, every code is executable. So the UI.start_timer acts
like a background process.

···

On 11/10/11 11:20, lover ruby wrote:

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

Then you must not #join in the method that start the thread as Sam explained.

Example:

Kind regards

robert

···

On Tue, Oct 11, 2011 at 8:08 AM, lover ruby <huynh_ngoc_5@yahoo.com> wrote:

Sam Duncan wrote in post #1025958:

On 11/10/11 11:20, lover ruby wrote:

     sleep\(\[interval \- elapsed, 0\]\.max\)

---------------------------------------------------
But it never prints out "Doing other stuff..."

How can I make it print out like
"Doing other stuff..."
1318284723
1318284728
1318284733

Thanks

Try this;

module Timer

@timer = nil

def Timer.repeat_every(interval)
@timer = Thread.new do
loop do
start_time = Time.now
yield
elapsed = Time.now - start_time
sleep([interval - elapsed, 0].max)
end
end
end

def Timer.stop
unless @timer.nil?
@timer.kill
@timer.join(1) # don't hang forever
@timer = nil
end
end

end

Timer.repeat_every(5) do
puts Time.now.to_i
end

puts "Doing other stuff..."
sleep 10
puts "Stopping timer"
Timer.stop

As far as I can tell your execution is hanging on the join which will
never return as the timer thread is in an infinite loop =]

Hope that helps
Sam

Thanks for help.
The result is
1318313034Doing other stuff...

1318313039

And stop. Even I remove Timer.stop.

I want something like UI.start_timer in Google sketchup. After
UI.start_timer, every code is executable. So the UI.start_timer acts
like a background process.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Robert Klemme wrote in post #1026082:

1318284733

   loop do
   @timer.kill

Sam

UI.start_timer, every code is executable. So the UI.start_timer acts
like a background process.

Then you must not #join in the method that start the thread as Sam
explained.

Example:
Timer example · GitHub

Kind regards

robert

Thanks
I tried you code, but still need sleep 20. what I really want

require 'timer'
Timer.repeat_every(5) do
  puts Time.now.to_i
end

puts "Doing other stuff..."
#sleep 20

The output will be
"Doing other stuff..."
1318348633
1318348638
1318348643
1318348633
1318348638
1318348643
..........Forever, always print out number every 5 seconds

···

On Tue, Oct 11, 2011 at 8:08 AM, lover ruby <huynh_ngoc_5@yahoo.com> > wrote:

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

Can you explain what you mean by "still need sleep 20"?

Sam

···

On 12/10/11 05:04, lover ruby wrote:

Robert Klemme wrote in post #1026082:

On Tue, Oct 11, 2011 at 8:08 AM, lover ruby<huynh_ngoc_5@yahoo.com> >> wrote:

1318284733

    loop do
    @timer.kill

Sam

UI.start_timer, every code is executable. So the UI.start_timer acts
like a background process.

Then you must not #join in the method that start the thread as Sam
explained.

Example:
Timer example · GitHub

Kind regards

robert

Thanks
I tried you code, but still need sleep 20. what I really want

require 'timer'
Timer.repeat_every(5) do
   puts Time.now.to_i
end

puts "Doing other stuff..."
#sleep 20

The output will be
"Doing other stuff..."
1318348633
1318348638
1318348643
1318348633
1318348638
1318348643
..........Forever, always print out number every 5 seconds

Then you better exchange foreground and background task:

Thread.new do
  puts "Doing other stuff..."
end

loop do
  puts Time.now.to_i
  sleep 5
end

Kind regards

robert

···

On Tue, Oct 11, 2011 at 6:04 PM, lover ruby <huynh_ngoc_5@yahoo.com> wrote:

Robert Klemme wrote in post #1026082:

On Tue, Oct 11, 2011 at 8:08 AM, lover ruby <huynh_ngoc_5@yahoo.com> >> wrote:

1318284733

loop do
@timer.kill

Sam

UI.start_timer, every code is executable. So the UI.start_timer acts
like a background process.

Then you must not #join in the method that start the thread as Sam
explained.

Example:
Timer example · GitHub

Kind regards

robert

Thanks
I tried you code, but still need sleep 20. what I really want

require 'timer'
Timer.repeat_every(5) do
puts Time.now.to_i
end

puts "Doing other stuff..."
#sleep 20

The output will be
"Doing other stuff..."
1318348633
1318348638
1318348643
1318348633
1318348638
1318348643
..........Forever, always print out number every 5 seconds

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Sam Duncan wrote in post #1026126:

Then you must not #join in the method that start the thread as Sam

1318348633
1318348638
1318348643
1318348633
1318348638
1318348643
..........Forever, always print out number every 5 seconds

Can you explain what you mean by "still need sleep 20"?

Sam

Hi Sam
I understand now. The reason I said "still need sleep 20" was:

I had experience with GUI application which is always on. So there was
no need for sleep command.

But now I have a cmd (Windows DOS, xterm) application which terminates
at the last command. The only way to keep program alive is sleep
command. So to keep it alive forever, I change sleep 20 to sleep.

It is really my fault; I did think in GUI world for cmd world.
Thanks for help, Sam. I apply your advanced Timer class in my program.

Ruby lover.

···

On 12/10/11 05:04, lover ruby wrote:

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

Oh, I think I understand now =]

glhf

Sam

···

On 12/10/11 09:24, lover ruby wrote:

Sam Duncan wrote in post #1026126:

On 12/10/11 05:04, lover ruby wrote:

Then you must not #join in the method that start the thread as Sam

1318348633
1318348638
1318348643
1318348633
1318348638
1318348643
..........Forever, always print out number every 5 seconds

Can you explain what you mean by "still need sleep 20"?

Sam

Hi Sam
I understand now. The reason I said "still need sleep 20" was:

I had experience with GUI application which is always on. So there was
no need for sleep command.

But now I have a cmd (Windows DOS, xterm) application which terminates
at the last command. The only way to keep program alive is sleep
command. So to keep it alive forever, I change sleep 20 to sleep.

It is really my fault; I did think in GUI world for cmd world.
Thanks for help, Sam. I apply your advanced Timer class in my program.

Ruby lover.