From: Paul Brannan Date: 2007-04-27T22:37:56+09:00 Subject: Re: 10 millisecond delay/callback On Fri, Apr 27, 2007 at 04:57:21AM +0900, Earle Clubb wrote: > irb(main):001:0> 0.upto(25) do > irb(main):002:1* puts Time.now.usec/1000 > irb(main):003:1> STDOUT.flush > irb(main):004:1> sleep 0.01 > irb(main):005:1> end > 105 > 132 > 143 I believe part of the problem is that you are not correcting for the time that ruby spends in the loop. In [ruby-talk:42003] Dave Thomas proposed this solution: def every(period) base = last = Time.now.to_f count = 0 loop do now = Time.now.to_f actual_secs = now - base expected_secs = period * count correction = expected_secs - actual_secs correction = -period if correction < -period select(nil, nil, nil, period + correction) now = Time.now last = now.to_f count += 1 yield(now) end end Which I've tested using this code: n = 0 every(0.01) do puts Time.now.usec / 1000 n += 1 break if n == 25 end And got this output on Linux 2.6.5: [pbrannan@zaphod tmp]$ ruby test.rb 37 47 57 67 77 87 97 107 117 127 137 147 157 167 177 187 197 207 217 227 237 247 257 267 277 You'll still get problems if the amount of time you spend doing work in the loop exceeds 0.01 second. Paul