Erlang и process_flag (trap_exit, true) - PullRequest
16 голосов
/ 17 июля 2011

После просмотра скриншотов Pragmatic Studio на Erlang в последнем видео на Супервизорах упоминалось, что для того, чтобы супервизор получил уведомление об одном из его дочерних элементов, чтобы он мог правильно его перезапустить, дочерний элемент должен зарегистрироваться с помощью 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, процесс завершается, если он получает сигнал выхода, отличный от нормального, и сигнал выхода распространяется на связанные процессы. Процессы подачи заявок обычно не должны задерживать выходы .`

Ответы [ 3 ]

27 голосов
/ 17 июля 2011

Супервизоры используют ссылки и выходы ловушек, чтобы они могли отслеживать своих детей и перезапускать их при необходимости. Дочерние процессы не должны перехватывать выходы для надлежащего управления их супервизорами, в действительности они должны перехватывать только тогда, когда им конкретно необходимо знать, что какой-то процесс, с которым они связаны, умирает и не желает сбоя сами по себе.

Поведение OTP способно правильно обрабатывать надзор, если он в ловушке или не в ловушке.

26 голосов
/ 17 июля 2011

У вас есть 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.
17 голосов
/ 21 июля 2011

В Erlang процессы могут быть связаны вместе. Эти ссылки являются двунаправленными. Каждый раз, когда процесс умирает, он отправляет сигнал выхода всем связанным процессам. У каждого из этих процессов будет включен или отключен флаг trapexit . Если флаг отключен (по умолчанию), связанный процесс завершится сбоем, как только получит сигнал на выход. Если флаг был активирован вызовом system_flag(trap_exit, true), процесс преобразует полученный сигнал выхода в сообщение о выходе , и он будет не сбой. Выходное сообщение будет поставлено в очередь в своем почтовом ящике и будет рассматриваться как обычное сообщение.

Если вы используете OTP-супервизоры, они позаботятся о вас и о флагах trap_exit, поэтому вам не нужно об этом заботиться.

Если вы реализуете механизм контроля, который, вероятно, и предназначен для скриншотов (вы еще не видели), вам придется позаботиться о функции trap_exit.

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