[erlang-questions] perform a function on a fixed time interval
Hynek Vychodil
hynek@REDACTED
Tue Aug 24 12:34:32 CEST 2010
use timer:send_interval/2,3
On Tue, Aug 24, 2010 at 12:15 PM, Roberto Ostinelli <roberto@REDACTED> wrote:
> dear list,
>
> i have a loop process which needs to perform a computation every 1000
> ms. this process needs also to receive messages from external
> processes.
>
> the issue arises from the fact that in every normal erlang loop, the
> 'after' statement is called only if no messages are receive by the
> process for a specific timeout.
>
> this is more or less how i could write a process which executes a
> computation every 1000 ms.
>
> the send_loop/2 emulates the external sending of messages, main_loop/1
> is the process which must receive external processes messages and
> ensure to perform a computation every 1000 ms. you may run the code
> from the console with test:start/0.
>
> -----------------------------------
>
> -module(test).
> -compile(export_all).
>
> start() ->
> % start main loop
> Pid = spawn(?MODULE, main_loop, [now()]),
> % start sender loop
> send_loop(Pid, 20),
> Pid ! shutdown.
>
> % send 20 messages every 500 ms
> send_loop(_Pid, 0) -> ok;
> send_loop(Pid, Count) ->
> receive
> after 500 ->
> Pid ! test,
> send_loop(Pid, Count - 1)
> end.
>
> main_loop(LastUpdate) ->
> receive
> shutdown ->
> shutdown;
> test ->
> io:format("received test message~n"),
> Now = now(),
> case timer:now_diff(Now, LastUpdate) / 1000 >= 1000 of
> true ->
> compute(),
> main_loop(Now);
> false ->
> main_loop(LastUpdate)
> end
> after 1000 ->
> compute(),
> main_loop(now())
> end.
>
> compute() ->
> io:format("ping~n").
>
> -----------------------------------
>
> another solution would imply running a timer process which would
> signal the main_loop when to perform the computation. you may run the
> code from the console with test:start/0.
>
> -----------------------------------
>
> -module(test).
> -compile(export_all).
>
> start() ->
> % start main loop
> Pid = spawn(?MODULE, main_loop, []),
> % start sender loop
> send_loop(Pid, 20),
> Pid ! shutdown.
>
> % send 20 messages every 500 ms
> send_loop(_Pid, 0) -> ok;
> send_loop(Pid, Count) ->
> receive
> after 500 ->
> Pid ! test,
> send_loop(Pid, Count - 1)
> end.
>
> main_loop() ->
> % start timer loop
> TimerPid = spawn(?MODULE, timer, [self()]),
> main_loop(TimerPid).
> main_loop(TimerPid) ->
> receive
> shutdown ->
> TimerPid ! shutdown;
> test ->
> io:format("received test message~n"),
> main_loop(TimerPid);
> compute ->
> compute(),
> main_loop(TimerPid)
> end.
>
> % send a ping every 1000 ms to the main_loop
> timer(MainPid) ->
> receive
> shutdown ->
> shutdown
> after 1000 ->
> MainPid ! compute,
> timer(MainPid)
> end.
>
> compute() ->
> io:format("ping~n").
>
> -----------------------------------
>
> which one would you choose, or is there any other way to perform this better?
>
> thank you,
>
> r.
>
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED
>
>
--
--Hynek (Pichi) Vychodil
Analyze your data in minutes. Share your insights instantly. Thrill
your boss. Be a data hero!
Try GoodData now for free: www.gooddata.com
More information about the erlang-questions
mailing list