Erlang - 调用io时接收超时消息:格式
我有以下程序。但是,在追踪生成的进程时,我会看到一条带有超时的跟踪消息,如以下跟踪中所示。Erlang - 调用io时接收超时消息:格式
start() ->
register(addone, spawn(addone, loop, [])).
loop() ->
receive
{request, Pid, Msg} ->
io:format("log ~n", []),
loop();
{stop, _Reason} ->
stop
end.
我执行这个过程具有以下功能:观察
run() ->
addone:start(),
dbg:start(),
dbg:tracer(),
dbg:p(whereis(addone), [c,m]),
dbg:tpl({'_','_','_'},[{'_',['true'],[{'silent', 'false'}]}]),
addone:request(4).
跟踪如下:
1> addone_scenarios:run().
log
(<0.32.0>) << {request,<0.30.0>,4}
(<0.32.0>) call io:format("log ~n",[])
(<0.32.0>) call io:default_output()
(<0.32.0>) call erlang:group_leader()
(<0.32.0>) call io:format(<0.23.0>,"log ~n",[])
(<0.32.0>) call io:o_request(<0.23.0>,{format,"log ~n",[]},format)
(<0.32.0>) call io:request(<0.23.0>,{format,"log ~n",[]})
(<0.32.0>) call io:io_request(<0.23.0>,{format,"log ~n",[]})
(<0.32.0>) call io:bc_req(<0.23.0>,{put_chars,unicode,io_lib,format,["log ~n",[]]},false)
(<0.32.0>) call net_kernel:dflag_unicode_io(<0.23.0>)
(<0.32.0>) call io:execute_request(<0.23.0>,{false,{put_chars,unicode,io_lib,format,["log ~n",[]]}})
(<0.32.0>) call erlang:monitor(process,<0.23.0>)
(<0.32.0>) <0.23.0> ! {io_request,<0.32.0>,<0.23.0>,
{put_chars,unicode,io_lib,format,["log ~n",[]]}}
(<0.32.0>) call io:wait_io_mon_reply(<0.23.0>,#Ref<0.0.0.29>)
(<0.32.0>) << {io_reply,<0.23.0>,ok}
(<0.32.0>) call erlang:demonitor(#Ref<0.0.0.29>)
(<0.32.0>) << timeout
(<0.32.0>) call addone:loop()
什么奇怪的是,收到超时跟踪消息。当我删除io:format(...)
时,未收到此消息。有人可以指出什么是可能的原因吗?
编辑:我已更新跟踪以包含所有功能的调用,也许它可能有所帮助。
我的两分钱在这里:如果您阅读erlang doc for dbg,您也会看到该超时消息,我认为注册打印调试消息的io_server产生了一个专用的进程,可以缓解大型阻塞I/O跟踪的性能,但过了一段时间,没有任何东西被追踪,它只是放弃侦听的“套接字”(我的意思是从erlang传递消息系统的角度来看套接字)。 你的确看到io_request和io_reply并从< 0.23.0>是打印服务器,我想你可以简单地忽略它作为一个(无用)进一步调试消息。
在IO模块,其中有在功能io:wait_io_mon_reply/2
其中它等待回复到IO请求消息超时中的唯一位置。为了确保客户端进程不会挂起,io进程已经被监视以检测它在返回应答之前死亡的情况。该io:wait_io_mon_reply/2
必须处理的它可以接收和也清理的情况下,消息队列它得到多方面的回报,例如监控被关闭之前都回复消息和死亡消息的发送过程的各种情况。由于erlang通信的非确定性异步特性,这发生并且必须被照顾。
处理这种标准方式是通过做(取直出功能):
receive
{io_reply, From, Reply} ->
erlang:demonitor(Mref),
receive
{'DOWN', Mref, _, _, _} -> true
after 0 -> true
end,
Reply;
使用的0
超时意味着你永远等待,如果该消息是不存在的,但你得到超时。我猜测这就是你在跟踪中看到的。这不是一个错误,而只是编写代码的方式。没有这样做的可行替代方案。
这意味着,在某种程度上,你将不得不忽略此超时,或者只是接受超时作为该计划的一个自然组成部分,而不是某种形式的“异常”或错误的。
如果我已经明白它是如何工作的。
我忽略这个跟踪消息的问题是,我正在构建一个工具来分析程序的痕迹,并根据它收到的内容采取行动..所以我不能选择哪些超时消息我可以忽略,哪些不是不幸的 – aseychell 2012-02-14 18:09:38