timer作為其計時器:
erlang的計時器timer是通過一個唯一的timer進程實現的,該進程是一個gen_server,用戶通過timer:send_after和timer:apply_after在指定時間間隔后收到指定消息或執行某個函數,每個用戶的計時器都是一條記錄,保存在timer的ets表timer_tab中,timer的時序驅動通過gen_server的超時機制實現。若同時使用timer的用戶過多,則timer將響應不過來,成為瓶頸。
更好的方法是使用erlang的原生計時器erlang:send_after和erlang:start_timer,它們把計時器附着在進程自己身上。
看了段timer的源碼,如下:
schedule_cast(Msg, Default, Timers) -> %% Cancel the old timer... TRef = proplists:get_value(Msg, Timers), timer:cancel(TRef), %% Lookup the interval... IntervalKey = list_to_atom(atom_to_list(Msg) ++ "_interval"), Interval = sync_utils:get_env(IntervalKey, Default), %% Schedule the call... {ok, NewTRef} = timer:apply_after(Interval, gen_server, cast, [?SERVER, Msg]), %% Return the new timers structure... lists:keystore(Msg, 1, Timers, {Msg, NewTRef}).
這里的 timer:apply_after/4 這里為什么要這么寫? timer:apply_after(Time, Module, Function, Arguments) -> {ok, TRef} | {error, Reason}
沒有去調用timer:send_after 查看API后,apply_after是函數形式,send_after是發消息,查看timer的源碼之后,發現send_after就是調用apply_after,只是兩種寫法罷了。
timer的源碼鏈接:見 https://github.com/zhongwencool/otp/blob/maint/lib/stdlib/src/timer.erl
從學貴有恆的博客中,看到了下面的圖:
這是根據timer源碼,畫的流程圖,
timer的進程都是通過一個唯一的timer進程實現的,該進程是一個gen_server。建議使用erlang::send_after和erlang:start_timer,它們把計時器附着在進程自己身上.