From: Lars Christensen Date: 2009-08-11T00:07:00+09:00 Subject: Re: Soft realtime with EventMachine and timer resolution On Sat, Aug 8, 2009 at 7:40 AM, Macario Ortega wrote: >                loop do >                    @next += @interval >                    @tick += 1 >                    Thread.new do >                        tick >                    end >                    sleep @sleep_time until Time.now.to_f >= @next This seem to be a recurrent mistake when implementing periodic events. "Sleep X" does not ensure invokation every X seconds. It merely ensure that there will be "at least X" seconds of delay between each invokation. It could be X + 0.1, X + 1.0 or even 2 * X - there is simply no guarantee. The code in the loop apart from 'sleep' also takes time to execute (or the Garbage Collecter may run, or it can be suspended by the OS while not sleeping). This time spent here may be negilible most of the time, but OS's are not deterministic on this scale, so it may randomly take 10ms, 100ms or more if other processes on your computer are run at the same time. To get any sort of accuracy, you should always sleep "until the next event should occur" rather than a fixed time. For example: next = Time.now interval = 0.05 loop do invoke_periodic_event next += interval time_to_wait = next - Time.now sleep time_to_wait if time_to_wait > 0.0 end This will not avoid the jitter, but will compensate when it occurs. If jitter is extreme, you may want to add checks to reset the 'next' variable to something resonable if it gets too far behind. In music, jitter on a single beat may even add flavor to your music, but if you shift the time scale all time the time, you are confusing your listeners :-) EM's add_periodic_timer is also "flawed" in this way that it doesn't event attempt to invoke your method at fixed intervals but rather "sleeps" a fixed interval between each invokation.