读者可能说, 那我可以在消息里面加入TimerRef. 这个主意不错, 但是问题是在send_after调用返回之前, 你是无法得到TimerRef, 当然也就无从构造这个消息, 那就无法处理这个可能的超时信息, 就会破坏逻辑. 所以erts version 5.4.11 引入了, start_timer来解决这个问题. 它是自动的在超时后, 要发送消息前, 在消息...
这2个API都返回 TimerRef. 用户可以用这个TimerRef来取消定时器. 唯一的差别是在超时的时候发送的消息不同: send_after是Msg, start_timer是{timeout, TimerRef, Msg}. 问题就出在取消timer的时候. 如果这个timer还没有超时的时候, 那么取消就没问题. 如果超时了麻烦就来了, 这个消息已经有可能已经被放到目标...
若同时使用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), ...
自己的理解
erlang:start_timer(Time, self(), {'$gen_timer', Msg}). %% Returns Ref, sends Event after Time to the (then) current state. send_event_after(Time, Event) -> erlang:start_timer(Time, self(), {'$gen_event', Event}). %% Returns the remaing time for the timer if Ref referred to...
?ONE_HOUR - misc_timer:now_seconds() rem ?ONE_HOUR + (Num -1) * ?ONE_HOUR; ?DAY -> util:get_next_day_seconds(Now) - Now + (Num - 1) * ?ONE_DAY; _ -> ?ONE_WEEK end, timer:send_after(LeftTime * 1000, self(),{'do_timely_info', CallBack, Kind, Num}). ...
erlang中有两个延时发送消息的函数erlang:send_after/3, timer:send_after/3,有什么区别呢? 看下timer:send_after/3的源码 send_after(Time, Pid, Message) -> req(apply_after, {Time, {?MODULE, send, [Pid, Message]}}) req(Req, Arg) -> SysTime = system_time(), ensur
更好的方法是使用erlang的原生计时器erlang:send_after和erlang:start_timer,它们把计时器附着在进程自己身上。 8. 尾调用和尾递归: 尾调用和尾递归是erlang函数式语言最强大的优化,尽量保持函数尾部有尾调用或尾递归 9. 文件预读,批量写,缓存: 这些方式都是局部性的体现: ...
使用erlang:send_after/3或erlang:start_timer/3可以减少对单一进程的压力。 通过code:clash()函数可以检测代码中是否有module冲突 使用export时,将功能类似的接口组合在一起,并添加合理的注视,这样你的接口更清晰,别人使用起来更方便,有助于提高代码的可读性和易用性。 不要相信客户端的数据 定义数据结构时,最好...
1. 语法层面的 receive ... after ... 这个是opcode实现的,一旦timeout立即把process加到调度队列,使用频度比较高。 2. bif erlang:send_after(Time, Dest, Msg) -> TimerRef erlang:start_timer(Time, Dest, Msg) -> TimerRef 这个一旦timeout就给Dest发送一条消息,使用频度不是很高。