Erlang - 调用io:格式时接收超时消息 [英] Erlang - Receiving timeout messages when calling io:format

查看:126
本文介绍了Erlang - 调用io:格式时接收超时消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下程序。但是,当跟踪生成的进程时,我看到一个跟踪消息中的超时,可以在下面的跟踪中看到。

I have the following program. However, when tracing the spawned process, I am seeing a trace message with a timeout as can be seen in the trace below.

start() ->
    register(addone, spawn(addone, loop, [])).

loop() ->
receive
    {request, Pid, Msg} ->
        io:format("log ~n", []),
        loop();
    {stop, _Reason} ->
        stop
end.

我正在使用以下功能执行此过程:

I am executing this process with the following function:

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(...)时,不会收到此消息。有人可以指出可能是什么原因吗?

What is strange is the timeout trace message that is received. When I remove the io:format(...), this message is not received. Can someone indicate what can be the reason please?

编辑:我已经更新了跟踪,包括所有功能的调用,也许可能有帮助

EDIT: I have updated the tracing to include the call for all functions maybe it might help.

推荐答案

在io模块中,功能 io中有超时的唯一地方:wait_io_mon_reply / 2 它等待io请求消息的回复。为了确保客户端进程不会挂起,io进程已被监视,以检测在返回回复之前它死亡的情况。 io:wait_io_mon_reply / 2 必须处理可以接收的各种情况 AND 还可以清理消息队列,以防其发生多重返回,例如在监视关闭之前回复消息和进程死亡消息发送。由于erlang通信的非确定性的异步性质,这种情况发生并且必须被照顾。

The only place in the io module where there are timeouts in the function io:wait_io_mon_reply/2 where it waits for the reply to the io request message. To make sure the client process never hangs the io process has been monitored to detect the case where it dies before returning a reply. The io:wait_io_mon_reply/2 has to handle the various cases of what it can receive AND also clean-up the message queue in case it gets multiple returns, for example both a reply message and a process dying message send before the monitoring was turned off. Because of the non-deterministic asynchronous nature of erlang communication this happens and must be taken care of.

处理这种情况的标准方法是(直接从功能):

The standard way of handling this is by doing (taken straight out of the function):

receive
    {io_reply, From, Reply} ->
        erlang:demonitor(Mref),
        receive 
            {'DOWN', Mref, _, _, _} -> true
        after 0 -> true
        end,
        Reply;

使用超时 0 意味着你永远不会如果消息不在,请等待,但是您会收到超时。我猜这是你在踪迹中看到的。这不是一个错误,而只是代码的编写方式。这样做没有可行的替代方法。

Using a timeout of 0 means you never wait if the message is not there but you do get a timeout. I am guessing that this is what you see in the trace. It is not an error but just way the code is written. There is no viable alternative to doing it this way.

这意味着在某种程度上你不得不忽略这个超时,或者只是接受超时作为自然的一部分程序而不是某种形式的异常或错误。

This means that in some way you will have to ignore this timeout, or perhaps just accept timeouts as a natural part of the program and not some form of "exception" or error.

如果我已经了解了它的工作原理。

If I have understood how it works.

这篇关于Erlang - 调用io:格式时接收超时消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆