perform a function on a fixed time interval
Roberto Ostinelli
roberto@REDACTED
Tue Aug 24 12:15:37 CEST 2010
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.
More information about the erlang-questions
mailing list