Angular, AWS und Symfony Freelancer

Threads in Erlang

Mit Erlang lässt sich besonders einfach verteilter Code schreiben, der auf verschiedenen Threads Laufen kann ohne Probleme.

Erlang ist somit die Sprache der Wahl um verteilte Anwendungen zu schreiben.

Regeln bei Threads in Erlang

  • Threads greifen dabei nicht auf gemeinsamen Speicherraum zu, sondern kommunizieren nur über Messages miteinander, um Kollisionen auszuschließen.
  • Senden ist asynchron, für synchrone Nachrichten muss self() mitgesendet und ausgewertet werden (self gibt die eigene Pid aus)
  • zum Kommunizieren zwischen den Prozessen kann entweder die Pid mitgesendet werden (elegant), oder erfragt werden mit whereis()

Anbei ein kleines Beispiel bei dem die 3 verschiedenen Threads Berechnungen durchführen und sich die Ergebnisse untereinander zuschicken.

Das Programm soll eine Implementierung sein von Modulo 3, also ein Test, ob eine ganze Zahl durch3 teilbar ist, funktioniert leider nur nicht, aber die Threads kommunizieren erfolgreich miteinander, was man auf der Konsole sehen kann  🙂

Beispielaufruf der Funktion:

threadBsp(15).
threadBsp(Zahl)->

%Prozesse beenden, vom letzten Start, sonst Absturz, wenn vorher nicht beendet
killProcessWhenStarted(p1),
killProcessWhenStarted(p2),
killProcessWhenStarted(p3),

%Prozesse starten
Pid1 = spawn(p1()),
io:format("P1 gestartet mit Pid: ~w \n",[Pid1]),
register(p1, Pid1),

Pid2 = spawn(p2()),
io:format("P2 gestartet mit Pid: ~w \n",[Pid2]),
register(p2, Pid2),

Pid3 = spawn(p3()),
io:format("P3 gestartet mit Pid: ~w \n",[Pid3]),
register(p3, Pid3),

io:format("Prozesse gestartet, Berechnugn beginnt \n")
Pid1!{"Start", Zahl},

%ListPids = registered(),
%io:format("Registrierte Prozesse: ~w \n",[ListPids])
.

p1()->fun()->
    receive        
    {From, "end" } -> exit(self(), kill);
    {From,Zahl} ->
        io:fwrite("P1 hat Wert ~w bekommen \n",[Zahl]),
        Rest = Zahl rem 2,
        ErgebnisRund = Zahl div 2,
        if ErgebnisRund == 0 ->
                if Rest == 0 ->
                    io:fwrite("durch 3 teilbar! \n",[]);
                true ->
                    io:fwrite("nicht durch 3 teilbar! \n",[])
                end;
            true  ->
                if Rest == 0 ->
                    self()!{self(), ErgebnisRund};
                   true  ->
                       P2 = whereis(p2),
                       P2!{self(), ErgebnisRund}
                end,
                %continue running
                Loop = p1(),
                Loop()
        end
    end
end.

p2()->fun()->
    receive
        {From, "end" } -> exit(self(), kill);
        {From, Zahl} ->
            io:fwrite("P2 hat Wert ~w bekommen \n",[Zahl]),
            Rest = Zahl rem 2,
            ErgebnisRund = Zahl div 2,
            if ErgebnisRund == 0 ->
                    io:fwrite("nicht durch 3 teilbar! \n",[]);
                true  ->             
                if Rest == 0 ->
                       P3 = whereis(p3),
                       P3!{self(), ErgebnisRund};            
                   true  ->
                       From!{self(), ErgebnisRund}
                end,
                %continue running
                Loop = p2(),
                Loop()
            end
    end
end.

p3()->fun()->
    receive
        {From, "end" } -> exit(self(), kill);
        {From, Zahl} ->         
            io:fwrite("P3 hat Wert ~w bekommen \n",[Zahl]),
            Rest = Zahl rem 2,
            ErgebnisRund = Zahl div 2,
            if ErgebnisRund == 0 ->
                    io:fwrite("nicht durch 3 teilbar! \n",[]);
                true  ->             
                if Rest == 1 ->
                        From!{self(), ErgebnisRund};                           
                   true  ->
                        From!{self(), ErgebnisRund}
                end,
                %continue running
                Loop = p3(),
                Loop()
            end
    end
end.

killProcessWhenStarted(Name)->
    Pid = whereis(Name),
    if Pid /= undefined -> exit(Pid, kill);
       true  -> io:format("Prozesse beendet ~w \n", [Name])
    end
.

 


Posted

in

by

Tags:

Comments

Ein Kommentar zu „Threads in Erlang“

  1. Avatar von Johannes
    Johannes

    Schreckliche Erklärungen sind das hier. Erlang hat Prozesse, keine Threads und man darf ruhig erwähnen, dass diese nichts mit den Prozesses des OS zu tun haben, den wirren Sachen hier über asynchrone Nachrichten, self() mitsenden verstehe ich nur, weil ich vorher schon kannte.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert