В Erlang там какой-либо способ, которым отправитель сообщения может ожидать на ответе, таким образом, он только продолжает выполнение, как только сообщение было обработано?
И я имею в виду что-то вроде этого:
Actor ! DoSomething
Continue to this next line of code when DoSomething has been processed
Я знаю, что обратный вызов может быть сделан путем отправки Pid отправителя, но является там каким-либо другим способом ожидать?
Прежде всего необходимо понять, что Erlang был создан для работы с асинхронной передачей сообщений. Таким образом, единственный способ обеспечить синхронную передачу сообщений - это реализовать что-то вроде подтверждения.
Представьте себе два процесса, P1 и P2. P1 может запускать следующий код:
%% process P1 takes the Pid of P2 as a parameter
%% and a Message to pass on to P2
p1(P2, Message) ->
P2 ! {self(), Message},
receive
{P2, ok}
after 5000 -> % this section is optional, times out after 5s
exit("P2 didn't process this!") % this kills P1
end.
P2, со своей стороны, может просто запускать следующее:
p2() ->
receive
{From, Message} ->
io:format("P2 received message ~p~n",[Message]),
%% processing is done!
From ! {self(), ok}
end.
Таким образом, вы можете создать p2 как новый процесс. Этот будет сидеть в ожидании любого сообщения. Когда вы затем вызываете p1, он отправляет сообщение P2, который затем обрабатывает его ( io: format / 2
) и отвечает на P1. Поскольку P1 ждал ответа, внутри этого процесса не выполнялся дополнительный код.
Это основной и единственный способ реализовать блокировку вызовов. Предложения по использованию gen_server: call
примерно реализуют то, что я только что показал. Однако это скрыто от программиста.
Вы можете использовать блок получения :
http://www.erlang.org/doc/reference_manual/expressions.html#id2270724
Чтение из документа:
получить никогда не подводит. Выполнение приостанавливается, возможно на неопределенный срок, до тех пор, пока не придет сообщение, которое соответствует одному из шаблонов и с истинной защитной последовательностью .
Другими словами, отправьте сообщение и дождитесь ответа.
Нет, есть только асинхронная передача сообщений.
Если вы хотите немного пофилософствовать, то очень сложно автоматически определить, когда сообщение было обработано. Это когда сообщение прибыло в процесс, было получено, но еще не обработано, или когда оно было обработано принимающим процессом. Это похоже на автоматическое уведомление, когда кто-то «прочитал» мою почту. Да, они видели это, но они действительно читали?
Если принимающий процесс является gen_server, вы можете использовать gen_server:call
. Например:
gen_server:call(Pid, Message),
% At this point, we know that the other process has answered.
Просто зависит от ситуации jldupont. Если веб-браузер делает запрос к веб-машине для какого-либо долго работающего ресурса erlang, нет возможности использовать приведение для выполнения этого запроса.