如何实现一个接收两条消息并在Erlang中将两个数字加在一起的进程?

时间:2016-05-04 11:06:38

标签: process erlang message-queue

在Erlang中实现的进程adder2具有签名: adder2 (In0, In1, Kill, Out) -> ...

可以发送到此过程的三条消息如下所示 图表:{In0, Msg}{In1, Msg}{Kill},其中In0In1 函数的参数中提供了Kill并标识了其类型 消息。

进程本身等待Msg表示的输入消息 传达的整数值。一旦输入两次 收到后,它将这些总和输出到标识为Out的过程。

任何 在等待输入的同时,可以向其发送Kill消息 应该通过正常终止做出回应。

使用上面给出的签名提供此过程的实现。

我了解需要有In0In1Kill条消息的接收表达式。但是我不知道允许以任何顺序接收消息的正确语法,有人可以帮助我吗?

我也不确定将两个值加在一起的正确语法。

输出它们需要将它们分配给结果值,然后发送到Out流程,例如Out ! Result

1 个答案:

答案 0 :(得分:2)

首先,所有变量都以大写字母开头,因此Erlangers会将{In0, Msg}读为元组,其中两个元素都是可变的。如果您的意思是带有固定值的第一个元素的消息,您应该写{in0, Msg}{'In0', Msg},其中第一个元素是原子'in0''In0'。您可以使用adder2的变体来配置邮件的第一个元素,但它会更复杂。因此,如果我们希望消息{in0, Msg}{in1, Msg}kill(它不必是单元素元组。),解决方案可以是:

-module(adder2).

-export([start/1]).

start(Out) ->
    spawn(fun() -> adder2(Out) end).

adder2(Out) ->
    adder2(undefined, undefined, Out).

adder2(undefined, In1, Out) ->
    wait(undefined, In1, Out);
adder2(In0, undefined, Out) ->
    wait(In0, undefined, Out);
adder2(In0, In1, Out) ->
    Out ! In0 + In1,
    adder2(Out).

wait(In0, In1, Out) ->
    receive
        {in0, Msg} when is_integer(Msg) ->
            adder2(Msg, In1, Out);
        {in1, Msg} when is_integer(Msg) ->
            adder2(In0, Msg, Out);
        kill ->
            ok; % last in a chain of tail recursive functions so exit normal
        Msg ->
            io:format("~p: Unknown message: ~p~n", [self(), Msg]),
            adder2(In0, In1, Out)
    end.

Shell会话示例:

1> c(adder2).
{ok,adder2}
2> P = adder2:start(self()).
<0.43.0>
3> link(P).
true
4> process_flag(trap_exit, true).
false
5> P ! {foo, bar}.
<0.43.0>: Unknown message: {foo,bar}
{foo,bar}
6> P ! {in0, 2.3}.
<0.43.0>: Unknown message: {in0,2.3}
{in0,2.3}
7> P ! {in0, 2}.
{in0,2}
8> P ! {in1, 3}.
{in1,3}
9> flush().
Shell got 5
ok
10> P ! {in1, 2}.
{in0,2}
11> P ! {in1, 3}.  % rewrite previous value in wait/3
{in0,3}
12> P ! {in0, 4}.
{in1,4}
13> flush().     
Shell got 7
ok
14> P ! {in1, 3}.
{in1,3}
15> P ! kill.    
kill
16> flush().     
Shell got {'EXIT',<0.43.0>,normal}
ok