La mia descrizione del modello dell'attore è giusta?

13

Se ho capito, il modello degli attori è proprio come il modello a oggetti, ma con alcune differenze:

  1. OGNI oggetto genera il proprio thread separato e non è un problema anche quando si hanno migliaia di oggetti.
  2. Gli attori non interagiscono chiamando funzioni e ottenendo valori di ritorno, ma inviando e ricevendo messaggi.
  3. Se non violi il modello, la tua app utilizzerà la concorrenza in tutta la sua potenza senza rischi di condizioni di gara.
  4. Tutto quello che puoi fare in OO puoi farlo usando gli attori ma meglio, il problema è che tutto ciò che abbiamo codificato negli ultimi anni era basato su OO - ma una transizione è imminente.

Quindi, ad esempio, supponiamo di dover definire una classe / attore vettoriale 3d, creare due istanze e chiamare un'operazione somma su di esse.

OGGETTO ORIENTATO:

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

MODELLO ATTORE:

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
}

È così? O ho sbagliato completamente?

    
posta WindScar 28.10.2011 - 22:33
fonte

2 risposte

12

La risposta breve è no, non è corretta.

  1. inizia ragionevolmente corretto (ciascun attore, almeno potenzialmente, viene eseguito come thread indipendente), ma in seguito esce in gran parte dai binari. Non c'è niente riguardo al modello che fa funzionare un sacco di thread - questo dipende dall'implementazione. Al massimo, la facilità di creare molti thread mette sotto pressione l'implementazione per fornire threading efficienti. Almeno per quanto riguarda il modello, qualsiasi somiglianza tra attori e oggetti è per lo più casuale. "Oggetto" comporta implicazioni abbastanza specifiche su come combinare codice e dati. Un attore generalmente coinvolge sia codice che dati, ma implica poco sul modo in cui sono combinati (a parte il fatto che gli unici dati visibili al mondo esterno sono i messaggi).

  2. Il solito modo di descrivere l'interazione è come inviare un messaggio, sì. Non ho una citazione a portata di mano, ma qualcuno ha dimostrato molto tempo fa che meccanismi come le funzioni virtuali di C ++ sono isomorfi all'invio di messaggi (poiché le funzioni virtuali sono normalmente implementate, si sta utilizzando un offset in un vtable - ma se si inviato un offset in una tabella di messaggi, l'effetto sarebbe lo stesso).

  3. Non è proprio così semplice. Se riesci a trovare una copia, Henry Baker (con qualcun altro il cui nome non ricordo in questo momento) ha scritto un articolo sulle regole necessarie per la coerenza dei dati nel modello di attore.

  4. "Migliore" è altamente soggettivo nella migliore delle ipotesi. Alcuni problemi sono di natura molto parallela e coinvolgono in realtà un gran numero di entità essenzialmente autonome, con un'interazione minima principalmente asincrona. Quando questo è il caso, il modello di attore può funzionare davvero molto bene. Per altri problemi, non è proprio così. Alcuni problemi sono quasi interamente di natura seriale. Altre possono essere eseguite in parallelo, ma richiedono comunque una stretta sincronizzazione tra tali azioni (ad esempio, essenzialmente una modalità simile a SIMD, in cui si esegue un'istruzione alla volta, ma ciascuna istruzione agisce su un gran numero di elementi di dati). È certamente possibile risolvere entrambi questi tipi di problemi usando il modello degli attori - ma per tali problemi, spesso comporta una buona quantità di lavoro extra con poco o nessun guadagno in cambio.

risposta data 29.10.2011 - 02:16
fonte
2

Riguardo a 1: Ho lavorato con un'applicazione modellata su attore con filettatura singola (ish), quindi è possibile ignorare il numero di thread grande che questo suggerisce. AFAIK, i thread non sono oggetti leggeri in alcun modo, quindi probabilmente non è desiderabile averne uno per ogni attore, a seconda di quanti attori stai usando.

Riguardo a 3: sono abbastanza sicuro che le condizioni di gara possano accadere nei sistemi modellati dagli attori semplicemente a causa della logica di programmazione?

Riguardo a 4: definisci "migliore"? La mia esperienza è stata che la logica asincrona può essere molto più difficile da leggere rispetto alle cose sincrone. ad esempio, nell'esempio sopra riportato, non sai quale operazione è responsabile del risultato, quindi è necessario eseguire ulteriori tracciamenti dei messaggi. Una volta aggiunto e inclusi e altri messaggi nella logica, l'intento del codice è distribuito su più funzioni di invio / ricezione.

Detto questo, sono un grande fan del modello degli attori per gli strati superiori di un'applicazione. Può semplificare il disaccoppiamento, poiché aggiungere dipendenze è un po 'più difficile dell'aggiunta di una funzione. Inoltre, non ho molta esperienza con il livello più alto dei linguaggi Java, e altri paradigmi potrebbero supportare l'asincronia in un modo più fondamentale.

    
risposta data 28.10.2011 - 23:53
fonte