Il modello dell'attore opera sul passaggio dei messaggi. I singoli processi (attori) possono inviare messaggi in modo asincrono tra loro. Ciò che lo distingue da ciò che normalmente pensiamo come il modello di threading, è che non esiste (almeno in teoria) uno stato condiviso. E se si crede (giustamente, penso) che lo stato condiviso sia la radice di tutti i mali, allora il modello dell'attore diventa molto attraente.
Tuttavia, non dovremmo eccitarci. Il modello dell'attore non rende (contrariamente ad alcune accuse) impossibile avere deadlock. Il modello attore, inoltre, non impedisce di avere conflitti per le risorse tra processi diversi, ad esempio le code di messaggi. Il modello è solo "senza blocco" al di sopra di un certo livello. A un livello inferiore, per coordinare le code di messaggi, è ancora richiesto il blocco.
Un thread non può essere visto come un attore e inviare messaggi ad altri thread?
Ebbene sì e no. No, se stai solo usando l'approccio di mettere mutex intorno alle posizioni di memoria condivisa. Quindi i thread condividono questo stato: entrambi hanno accesso a questa memoria, possono sia leggerla, riscriverla, ecc. sotto. Ho messo insieme qualcosa di simile (molto male) dando a ogni thread una coda protetta da un mutex - solo per divertimento. Per avere un'idea di come viene gestita l'impedenza del thread dell'attore, vedere la mia domanda di un anno fa .
Posso utilizzare il modello attore in qualsiasi lingua utilizzando i thread in modo diverso?
Sì, ma ci vorrà un po 'più di lavoro. La tua lingua preferita potrebbe avere una libreria di passaggio di messaggi, quindi sarebbe la prima cosa da indagare. Inoltre, dovresti esaminare l'uso di strutture di dati immutabili. Si noti che se una struttura dati è immutabile, in sostanza hai affrontato il problema dello "stato condiviso": più thread possono contenere riferimenti a dati immutabili senza che accada nulla di male. C'è una ragione per cui i linguaggi degli attori tendono ad essere anche linguaggi funzionali (erlang, scala).
Potresti anche dare un'occhiata alla memoria transazionale del software, che è un modello diverso ma anche avvincente. Clojure è il mio esempio preferito di questo.