В Erlang там какой-либо способ, которым отправитель сообщения может ожидать на ответе?

В Erlang там какой-либо способ, которым отправитель сообщения может ожидать на ответе, таким образом, он только продолжает выполнение, как только сообщение было обработано?

И я имею в виду что-то вроде этого:

Actor ! DoSomething
Continue to this next line of code when DoSomething has been processed

Я знаю, что обратный вызов может быть сделан путем отправки Pid отправителя, но является там каким-либо другим способом ожидать?

9
задан Zubair 22 February 2010 в 17:27
поделиться

5 ответов

Прежде всего необходимо понять, что 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 примерно реализуют то, что я только что показал. Однако это скрыто от программиста.

22
ответ дан 4 December 2019 в 08:33
поделиться

Вы можете использовать блок получения :

http://www.erlang.org/doc/reference_manual/expressions.html#id2270724

Чтение из документа:

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

Другими словами, отправьте сообщение и дождитесь ответа.

4
ответ дан 4 December 2019 в 08:33
поделиться

Нет, есть только асинхронная передача сообщений.

Если вы хотите немного пофилософствовать, то очень сложно автоматически определить, когда сообщение было обработано. Это когда сообщение прибыло в процесс, было получено, но еще не обработано, или когда оно было обработано принимающим процессом. Это похоже на автоматическое уведомление, когда кто-то «прочитал» мою почту. Да, они видели это, но они действительно читали?

2
ответ дан 4 December 2019 в 08:33
поделиться

Если принимающий процесс является gen_server, вы можете использовать gen_server:call. Например:

gen_server:call(Pid, Message),
% At this point, we know that the other process has answered.
4
ответ дан 4 December 2019 в 08:33
поделиться

Просто зависит от ситуации jldupont. Если веб-браузер делает запрос к веб-машине для какого-либо долго работающего ресурса erlang, нет возможности использовать приведение для выполнения этого запроса.

-7
ответ дан 4 December 2019 в 08:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: