Wenn ich verstanden habe, ist das Darstellermodell genau wie das Objektmodell, aber mit ein paar Unterschieden:
- JEDES Objekt erzeugt einen eigenen separaten Thread und es ist kein Problem, auch wenn Sie Tausende von Objekten haben.
- Akteure interagieren nicht durch Aufrufen von Funktionen und Abrufen von Rückgabewerten, sondern durch Senden und Empfangen von Nachrichten.
- Wenn Sie nicht gegen dieses Modell verstoßen, nutzt Ihre App die Parallelität ohne das Risiko von Rennbedingungen.
- Alles, was Sie in OO tun können, können Sie mit Schauspielern tun, aber besser. Das Problem ist, dass alles, was wir in den letzten Jahren codiert haben, OO-basiert war - aber ein Übergang steht bevor.
Nehmen wir zum Beispiel an, ich muss eine 3D-Vektorklasse / einen 3D-Akteur definieren, zwei Instanzen erstellen und eine Summenoperation für sie aufrufen.
OBJEKTORIENTIERTEN:
class V3d {
constructor V3d(x,y,z) //bla
float x,y,z;
function sum(V3d b)
{
return V3d(x+b.x,y+b.y,z+b.z);
}
}
//using:
mySum = V3d(1,2,3).sum(V3d(3,2,1)) //creates 2 instances, sum, returns instantly
drawPoint(mySum) //uses the result
SCHAUSPIELER-MODELL:
actor V3d
{
constructor V3d(x,y,z) //bla
float x,y,z;
loop
{
receive 'sum',b:V3d :
send(caller,'sumResult',V3d(x+b.x,y+b.y,z+b.z))
}
}
//using:
send(V3d(1,2,3),'sum',V3d(3,2,1)) //creates 2 instances, send to the first one a request to sum with the second one
loop
{
receive 'sumResult',result:
drawPoint(result) //receives result and draws it
}
Ist es das? Oder liege ich völlig falsch?
Antworten:
Die kurze Antwort ist nein, es ist nicht richtig.
Startet einigermaßen korrekt (jeder Actor führt zumindest potentiell als eigenständiger Thread aus), geht dann aber größtenteils von den Schienen. Es gibt nichts an dem Modell , was dazu führt, dass viele Threads gut funktionieren - das hängt von der Implementierung ab. Die einfache Erstellung vieler Threads übt allenfalls Druck auf die Implementierung aus, um ein effizientes Threading bereitzustellen. Zumindest in Bezug auf das Modell ist jede Ähnlichkeit zwischen Schauspielern und Objekten meistens zufällig. "Objekt" hat ziemlich spezifische Auswirkungen auf die Art und Weise, wie Sie Code und Daten kombinieren. Ein Akteur wird im Allgemeinen sowohl Code als auch Daten einbeziehen, impliziert jedoch wenig darüber, wie sie kombiniert werden (abgesehen von der Tatsache, dass die einzigen Daten, die für die Außenwelt sichtbar sind, Nachrichten sind).
Die übliche Art, die Interaktion zu beschreiben, ist das Senden von Nachrichten, ja. Ich habe kein Zitat zur Hand, aber jemand hat vor langer Zeit bewiesen, dass Mechanismen wie virtuelle C ++ - Funktionen für das Senden von Nachrichten isomorph sind (da virtuelle Funktionen normalerweise implementiert sind, verwenden Sie einen Versatz in einer vtable - aber wenn Sie Wird stattdessen ein Offset in eine Nachrichtentabelle gesendet, ist der Effekt derselbe.
So einfach ist das nicht. Wenn Sie eine Kopie finden können, hat Henry Baker (mit jemand anderem, an dessen Namen ich mich noch nicht erinnere) eine Abhandlung über die Regeln geschrieben, die für die Datenkonsistenz im Actor-Modell erforderlich sind.
"Besser" ist bestenfalls höchst subjektiv. Einige Probleme sind von Natur aus sehr parallel und umfassen tatsächlich eine große Anzahl von im Wesentlichen autonomen Entitäten mit minimaler Interaktion, die hauptsächlich asynchron ist. In diesem Fall kann das Schauspielermodell sehr gut funktionieren. Bei anderen Problemen ist das wirklich nicht der Fall. Einige Probleme sind fast ausschließlich serieller Natur. Andere können parallel ausgeführt werden, erfordern jedoch eine enge Synchronisation zwischen diesen Aktionen (z. B. im Wesentlichen ein SIMD-ähnlicher Modus, in dem Sie jeweils einen Befehl ausführen, aber jeder Befehl auf eine große Anzahl von Datenelementen angewendet wird). Es ist sicherlich möglich, beide Arten von Problemen mit dem Akteurmodell zu lösen. Bei solchen Problemen ist jedoch häufig ein erheblicher Mehraufwand erforderlich, für den nur ein geringer oder gar kein Gewinn erzielt wird.
quelle
Zu 1: Ich habe mit einer von einem Akteur modellierten (ish) Thread-Anwendung gearbeitet, daher ist es durchaus möglich, die große Thread-Nummer zu ignorieren, die dies nahelegt. AFAIK, Threads sind keineswegs leichte Objekte, daher ist es wahrscheinlich nicht wünschenswert, für jeden Schauspieler einen zu haben, je nachdem, wie viele Schauspieler Sie verwenden.
Zu 3: Ich bin mir ziemlich sicher, dass Rennbedingungen in akteursmodellierten Systemen einfach aufgrund der Programmierlogik auftreten können.
Zu 4: Besser definieren? Ich habe die Erfahrung gemacht, dass asynchrone Logik viel schwieriger zu lesen ist als synchrone. Beispiel: In Ihrem obigen Beispiel wissen Sie nicht, welche Operation für welches Ergebnis verantwortlich ist. Daher ist eine zusätzliche Nachrichtenverfolgung erforderlich. Sobald dies hinzugefügt wurde und andere eingehende und ausgehende Nachrichten in der Logik enthalten sind, wird die Absicht des Codes auf mehrere Sende- / Empfangsfunktionen verteilt.
Trotzdem bin ich ein großer Fan von Schauspieler-Modellen für die oberen Ebenen einer Anwendung. Dies kann die Entkopplung erleichtern, da das Hinzufügen von Abhängigkeiten etwas schwieriger ist als das Hinzufügen einer Funktion. Ich habe auch nicht viel Erfahrung mit höheren Niveaus als Java-Sprachen, und andere Paradigmen könnten Asynchronität auf grundlegendere Weise unterstützen.
quelle