[erlang-questions] I'm having a SNAFU moment: timer:sleep/1
Bob Ippolito
bob@REDACTED
Tue Jan 13 10:44:09 CET 2015
The implementation of the timer module does rely on the same sleeping
machinery as receive (gen_server timeout) but it doesn't suffer drift by
using the technique that Darach suggested. It keeps track of timers in
terms of absolute time, and when it wakes up it samples the clock to see
which timers need to fire. Nothing special about the timer module, it just
uses a better algorithm... although it is a single gen_server process per
node, so having a lot of timers can be a bottleneck.
https://github.com/erlang/otp/blob/maint/lib/stdlib/src/timer.erl#L345-L375
On Tue, Jan 13, 2015 at 8:28 PM, Roberto Ostinelli <roberto@REDACTED>
wrote:
> Thank you Imants.
> Indeed, timer:apply_interval/4 actually works perfectly, no timer
> weirdness. I guess the implementation is not depending on the normal
> receive..after..end loop.
>
> For others interested, here's a working code example:
>
> -module(test).
> -export([call_periodical/2]).
> -export([periodical_fun/1]).
>
> call_periodical(Num, IntervalMs) ->
> Start = epoch_time_ms(),
> {ok, TRef} = timer:apply_interval(IntervalMs, ?MODULE, periodical_fun,
> [self()]),
> wait(Num),
> io:format("Finished in ~p microseconds.~n", [epoch_time_ms() - Start]),
> timer:cancel(TRef).
>
> wait(0) -> ok;
> wait(Num) ->
> receive
> ok -> wait(Num - 1);
> _ -> ok
> end.
>
> periodical_fun(Pid) ->
> Pid ! ok.
>
> epoch_time_ms() ->
> {Mega, Sec, Micro} = os:timestamp(),
> (Mega * 1000000 + Sec) * 1000 + round(Micro / 1000).
>
>
> Running it:
>
> Erlang/OTP 17 [erts-6.3] [source] [64-bit] [smp:8:8] [async-threads:10]
> [hipe] [kernel-poll:false] [dtrace]
>
> Eshell V6.3 (abort with ^G)
> 1> c(test).
> {ok,test}
> 2> test:call_periodical(1000, 10).
> Finished in 10004 microseconds.
> {ok,cancel}
> 3> test:call_periodical(2000, 10).
> Finished in 20002 microseconds.
> {ok,cancel}
> 4> test:call_periodical(10000, 1).
> Finished in 10002 microseconds.
> {ok,cancel}
> 5> test:call_periodical(20000, 1).
> Finished in 20000 microseconds.
> {ok,cancel}
> 6> test:call_periodical(1000, 1).
> Finished in 1002 microseconds.
> {ok,cancel}
>
> Where everything works as expected.
>
> Thank you everyone!
>
> Best,
> r.
>
>
> On Mon, Jan 12, 2015 at 6:14 PM, Imants Cekusins <imantc@REDACTED> wrote:
>
>> btw CPU looked ok: was spread across cores and did not max out.
>>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150113/dc386403/attachment.htm>
More information about the erlang-questions
mailing list