Erlang и process_flag (trap_exit, true)
После просмотра экрана Pragmatic Studio на Erlang последнее видео на Supervisors упомянуло, что для того, чтобы супервизор получил уведомление об одном из своих дочерних элементов, чтобы он мог правильно перезапустить его, ребенок должен зарегистрироваться в process_flag(trap_exit, true)
. Возможно, я просто неправильно понял автора (и возможности ОЧЕНЬ высоки, что я неправильно понял), но я думал, что руководители автоматически узнают, когда их дети умирают (возможно, через spawn_link или что-то подобное в фоновом режиме). Это действительно необходимо? Когда нужно использовать process_flag (trap_exit, true) в реальном мире, потому что в документации явно указано следующее:
http://www.erlang.org/doc/man/erlang.html#process_flag-2
process_flag (trap_exit, Boolean)
Если для параметра trap_exit установлено значение true, сигналы выхода, поступающие в процесс, преобразуются в сообщения {'EXIT', From, Reason}, которые могут приниматься как обычные сообщения. Если для параметра trap_exit установлено значение false, процесс завершается, если он принимает выходной сигнал, отличный от нормального, и сигнал выхода распространяется на связанные процессы. Обычно процессы приложений не прерывают выходы. ``
Ответы
Ответ 1
У вас есть 3 идиомы:
1/Мне все равно, умирает ли мой дочерний процесс:
spawn(...)
2/Я хочу сбой при сбое моего дочернего процесса:
spawn_link(...)
3/Я хочу получить сообщение, если мой дочерний процесс завершается (обычно или нет):
process_flag(trap_exit, true),
spawn_link(...)
Пожалуйста, просмотрите этот пример и попробуйте разные значения (инвертируйте с 2 или 0, чтобы спровоцировать исключение и использовать trap_exit или нет):
-module(play).
-compile(export_all).
start() ->
process_flag(trap_exit, true),
spawn_link(?MODULE, inverse, [2]),
loop().
loop() ->
receive
Msg -> io:format("~p~n", [Msg])
end,
loop().
inverse(N) -> 1/N.
Ответ 2
Супервизоры используют ссылки и ловушки, чтобы они могли отслеживать своих детей и перезапускать их, когда это необходимо. В дочерних процессах не приходится улавливать выходы, чтобы их надлежащим образом управляли их руководители, действительно, они должны ловить ловушку только тогда, когда им необходимо знать, что какой-то процесс, с которым они связаны, умирает, и они не хотят рушиться.
Поведение OTP способно правильно обрабатывать наблюдение, если они оказались в ловушке или не захвачены.
Ответ 3
В Erlang процессы могут быть связаны друг с другом. Эти ссылки двунаправлены. Всякий раз, когда процесс умирает, он посылает выходной сигнал всем связанным процессам. Каждый из этих процессов будет иметь флаг trapexit, который будет включен или отключен. Если флаг отключен (по умолчанию), связанный процесс выйдет из строя, как только он получит сигнал выхода. Если флаг был активирован вызовом system_flag(trap_exit, true)
, процесс преобразует полученный сигнал выхода в сообщение о выходе, и он будет не сбой. Сообщение о выходе будет помещено в очередь в своем почтовом ящике и будет рассматриваться как нормальное сообщение.
Если вы используете супервизоры OTP, они заботятся о флажках и деталях trap_exit для вас, поэтому вам не нужно заботиться об этом.
Если вы реализуете механизм наблюдения, возможно, это то, о чем идет речь в экране (не видели), вам нужно будет позаботиться об этой проблеме trap_exit.