前段时间arksea 同学提出这个问题, 因为文档里面写的很不明白.
erlang:send_after(Time, Dest, Msg) -> TimerRef
Time = int()
0 <= Time <= 4294967295
Dest = pid() | RegName
LocalPid = pid() (of a process, alive or dead, on the local node)
Msg = term()
TimerRef = ref()
Starts a timer which will send the message Msg to Dest after Time milliseconds.
If Dest is an atom, it is supposed to be the name of a registered process. The process referred to by the name is looked up at the time of delivery. No error is given if the name does not refer to a process.
If Dest is a pid, the timer will be automatically canceled if the process referred to by the pid is not alive, or when the process exits. This feature was introduced in erts version 5.4.11. Note that timers will not be automatically canceled when Dest is an atom.
See also erlang:start_timer/3, erlang:cancel_timer/1, and erlang:read_timer/1.
Failure: badarg if the arguments does not satisfy the requirements specified above.
erlang:start_timer(Time, Dest, Msg) -> TimerRef
Time = int()
0 <= Time <= 4294967295
Dest = LocalPid | RegName
LocalPid = pid() (of a process, alive or dead, on the local node)
RegName = atom()
Msg = term()
TimerRef = ref()
Starts a timer which will send the message {timeout, TimerRef, Msg} to Dest after Time milliseconds.
If Dest is an atom, it is supposed to be the name of a registered process. The process referred to by the name is looked up at the time of delivery. No error is given if the name does not refer to a process.
If Dest is a pid, the timer will be automatically canceled if the process referred to by the pid is not alive, or when the process exits. This feature was introduced in erts version 5.4.11. Note that timers will not be automatically canceled when Dest is an atom.
See also erlang:send_after/3, erlang:cancel_timer/1, and erlang:read_timer/1.
Failure: badarg if the arguments does not satisfy the requirements specified above.
表面上看这2个API没有什么大的差别,使用上也一样, 那为什么要搞二个呢? 好奇怪!
好, 让我们来好好研究下典型应用.
这2个API都返回 TimerRef. 用户可以用这个TimerRef来取消定时器. 唯一的差别是在超时的时候发送的消息不同: send_after是Msg, start_timer是{timeout, TimerRef, Msg}.
问题就出在取消timer的时候. 如果这个timer还没有超时的时候, 那么取消就没问题. 如果超时了麻烦就来了, 这个消息已经有可能已经被放到目标进程的消息队列里,等待派遣处理了.
这时候send_after里面存放的是Msg, 那用户如何知道Msg是对于那个TimerRef的呢? 读者可能说, 那我可以在消息里面加入TimerRef. 这个主意不错, 但是问题是在send_after调用返回之前, 你是无法得到TimerRef, 当然也就无从构造这个消息, 那就无法处理这个可能的超时信息, 就会破坏逻辑.
所以erts version 5.4.11 引入了, start_timer来解决这个问题. 它是自动的在超时后, 要发送消息前, 在消息里面添加了{timeout, TimerRef, Msg}, 达到识别的目的.
结论: 文档里面一眼带过的东西, 其实是有很多设计方面的考虑, 要认真考虑它的存在的意义.
分享到:
相关推荐
erlang的timer和实现机制
Erlang是一种通用的面向并发的编程语言,它有瑞典电信设备制造商爱立信所辖的CS-Lab开发, 目的是创造一种可以应对大规模并发活动的编程语言和运行环境。
esl-erlang_23.0和rabbitmq-3.8.4windows版本 直接下载安装就行,可以直接下载就可安装,非常的方便 ,欢迎大家下载 注意事项: 1. Erlang版本和RabbitMQ版本要配套 (Erlang23.0, RabbitMQ3.8.4) 2. amd芯片请乖乖...
是erlang_otp_20.3 的win64安装包,内为exe文件,一路next即可安装完成 是适用于多线程、分布式开发的语言,也是如rabbitmq等重要工具的必须品 使用前需要配置环境变量:1.变量名为ERLANG_HOME,变量值为安装Erlang...
erlang_otp_win64_25.0
这个erlang23.0版本,根据rabbitMQ官网的介绍,可以和下面这几个版本的rabbitMQ配合使用: 3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 其他版本的rabbit,请移步其他资源下载
使用erlang:system_info(dirty_cpu_schedulers_online)进行检查。 如果未启用它们,它将返回badarg。 您可以使用以下方法检查您的呼叫是否正在肮脏的调度程序上处理:if(enif_is_on_dirty_scheduler(hp)){/...
erlang_otp_20.3_man开发手册,erlang_otp_20.3_man开发手册,erlang_otp_20.3_man开发手册
一个简单的模块系统,可轻松连接JavaScript和Erlang。 随附一些电池模块 入门 编译并启动一个shell: $ make $ make shell 确保已启动所有必需的应用程序,启动lib超级用户(请注意,这是一个单独的强制性步骤。...
实现了Erlang B/C功能,支持大容量计算
erlang-sd_notify-1.0-2.el7.x86_64.rpm
erlang-syntax_tools-19.3.6.4-1.el7.x86_64.rpm
cp _build/default/rel/erlang_release_example/erlang_release_example-0.1.0.tar.gz deploy/ (cd deploy && tar xzf erlang_release_example-0.1.0.tar.gz) ./deploy/bin/erlang_release_example console (erlang_...
Erlang_In_Anger pdf 语言
esl-erlang_19.3_osx_10.10_amd64.dmg
otp_win64_24.1.7.exe
erlang-gen_tcp手册,详细完整,网络tcp开发好东东
erlang官网下载速度太慢了,无法忍受,erlang_otp_src_22.3.tar.gz+rabbitmq-server-3.8.3-1.el6.noarch.rpm
Turbo Erlang: Approaching the Speed of C
实现爱尔兰B公式和爱尔兰C公式,功能齐全,适用于通信网课程中的实验。