Erlang - Получение сообщений о тайм-ауте при вызове формата io: - PullRequest
1 голос
/ 14 февраля 2012

У меня есть следующая программа. Однако при трассировке порожденного процесса я вижу сообщение трассировки с тайм-аутом, как видно из трассировки ниже.

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(...), это сообщение не получено. Кто-то может указать, в чем может быть причина, пожалуйста?

РЕДАКТИРОВАТЬ : Я обновил трассировку, чтобы включить вызов для всех функций, возможно, это может помочь.

Ответы [ 2 ]

1 голос
/ 15 февраля 2012

Единственное место в модуле io, где есть тайм-ауты в функции io:wait_io_mon_reply/2, где он ожидает ответа на сообщение запроса io. Чтобы убедиться, что клиентский процесс никогда не зависает, io-процесс отслеживается, чтобы обнаружить случай, когда он умирает, прежде чем возвращать ответ. io:wait_io_mon_reply/2 должен обрабатывать различные случаи того, что он может получить И , а также очищать очередь сообщений в случае, если он получает несколько возвратов, например, как ответное сообщение, так и сообщение об умирании процесса, отправленное до мониторинг был отключен. Из-за недетерминированной асинхронной природы эрланг-связи это происходит, и о ней нужно позаботиться.

Стандартный способ справиться с этим - сделать (вычеркнуть из функции):

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

Использование тайм-аута 0 означает, что вы никогда не ждете, если сообщения нет, но вы получаете тайм-аут. Я предполагаю, что это то, что вы видите в след. Это не ошибка, а просто способ написания кода. Нет такой альтернативы этому.

Это означает, что каким-то образом вам придется игнорировать этот тайм-аут или, возможно, просто принять тайм-ауты как естественную часть программы, а не какую-то форму «исключения» или ошибки.

Если я понял, как это работает.

0 голосов
/ 14 февраля 2012

Мои два цента здесь: если вы читаете erlang doc для dbg, вы также видите это сообщение о тайм-ауте, мое мнение таково, что io_server, зарегистрированный для печати отладочного сообщения, порождает выделенный процесс, который снижает производительность для огромной блокирующей трассировки ввода-вывода, но через некоторое время, когда ничего не отслеживается, он просто отбрасывает прослушивающий «сокет» (я имею в виду сокет с точки зрения системы передачи сообщений erlang). Действительно, вы видите io_request и io_reply с <0.23.0>, который является сервером печати, я думаю, вы можете просто проигнорировать его как (бесполезное) дальнейшее сообщение отладки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...