2016-05-04 13 views
-2

Der Prozess adder2, wie in Erlang implementiert, hat die Signatur: adder2 (In0, In1, Kill, Out) -> ...Wie implementiert man einen Prozess, der zwei Nachrichten empfängt und die beiden Zahlen in Erlang addiert?

Die drei Nachrichten, die an diesem Prozess gesendet werden können, werden wie in dem Diagramm gezeigt : {In0, Msg}, {In1, Msg} und {Kill}, wobei In0, In1 und Kill sind in den Argumenten der Funktion angegeben und identifizieren den Typ der Nachricht.

Der Prozess selbst wartet auf beide Eingangsnachrichten, wobei Msg einen ganzzahligen Wert darstellt, der kommuniziert wird. Sobald beide Eingänge empfangen wurden, wird die Summe dieser Eingänge an den als Out identifizierten Prozess ausgegeben.

Bei jeder Zeit, während auf die Eingaben gewartet wird, kann eine Kill Nachricht gesendet werden, auf die sie antworten sollte, indem sie normal beendet.

Stellen Sie eine Implementierung dieses Prozesses mit der oben angegebenen Signatur bereit.

Ich verstehe, dass es einen Empfang Ausdruck für In0, In1 und Kill Nachrichten geben muss. Allerdings kenne ich nicht die richtige Syntax, um die Nachrichten in beliebiger Reihenfolge empfangen zu können. Kann mir jemand dabei helfen?

Ich bin mir auch unsicher, die richtige Syntax für das Hinzufügen der beiden Werte zusammen.

Die Ausgabe würde erfordern, dass sie einem Ergebniswert zugewiesen und an den Out-Prozess gesendet werden, z. B. Out ! Result.

Antwort

2

Zuerst beginnen alle Variablen mit einem Großbuchstaben, also würde Erlangers {In0, Msg} als ein Tupel lesen, in dem beide Elemente variabel sind. Wenn Sie eine Nachricht mit dem ersten Element eines festen Werts meinen, sollten Sie {in0, Msg} oder {'In0', Msg} schreiben, wobei das erste Element ein Atom 'in0' oder 'In0' ist. Es kann Variante Ihres adder2 mit konfigurierbarem ersten Element der Nachricht geben, aber es wird komplizierter. Also, wenn wir Nachrichten erwarten {in0, Msg}, {in1, Msg} und kill (. Es ist kein Ein-Element-Tupel sein muss) kann die Lösung sein:

-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 Sitzung Beispiel:

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