如何使用精确时间(即10ms)定期运行Erlang进程

Gre*_*reg 5 erlang timer

我想每隔10ms运行一次定期的erlang进程(基于挂钟时间),10ms应该尽可能准确; 应该以什么方式实施它?

Hyn*_*dil 6

如果您想要真正可靠和准确的定期过程,您应该依赖实际的挂钟时间erlang:monotonic_time/0,1.如果你在Stratus3D答案中使用方法,你最终会落后.

start_link(Period) when Period > 0, is_integer(Period) ->
  gen_server:start_link({local, ?SERVER}, ?MODULE, Period, []).

...

init(Period) ->
    StartT = erlang:monotonic_time(millisecond),
    self() ! tick,
    {ok, {StartT, Period}}.

...

handle_info(tick, {StartT, Period} = S) ->
    Next = Period - (erlang:monotonic_time(millisecond)-StartT) rem Period,
    _Timer = erlang:send_after(Next, self(), tick),
    do_task(),
    {noreply, S}.
Run Code Online (Sandbox Code Playgroud)

你可以在shell中测试:

spawn(fun() ->
    P = 1000,
    StartT = erlang:monotonic_time(millisecond),
    self() ! tick,
    (fun F() ->
        receive
          tick ->
            Next = P - (erlang:monotonic_time(millisecond)-StartT) rem P,
            erlang:send_after(Next, self(), tick),
            io:format("X~n", []),
            F()
        end
      end)()
  end).
Run Code Online (Sandbox Code Playgroud)