Model aktora działa na przekazywaniu wiadomości. Poszczególne procesy (aktorzy) mogą wysyłać do siebie komunikaty asynchronicznie. To, co odróżnia to od tego, co zwykle uważamy za model wątkowy, to fakt, że nie ma (przynajmniej w teorii) żadnego wspólnego stanu. A jeśli ktoś wierzy (słusznie, jak sądzę), że wspólny stan jest źródłem wszelkiego zła, to model aktora staje się bardzo atrakcyjny.
Nie powinniśmy jednak zbytnio się ekscytować. Model aktora nie uniemożliwia (wbrew niektórym przypuszczeniom) impasu. Model aktora nie zapobiega również rywalizacji o zasoby między różnymi procesami - na przykład kolejkami komunikatów. Model jest „wolny od zamków” tylko powyżej pewnego poziomu. Na niższym poziomie, do koordynowania kolejek komunikatów, nadal wymagane jest blokowanie.
Czy wątek nie może być postrzegany jako aktor i wysyłać wiadomości do innych wątków?
Cóż, tak i nie. Nie, jeśli używasz tylko metody umieszczania muteksów wokół lokalizacji pamięci współdzielonej. Wtedy wątki dzielą ten stan - oba mają dostęp do tej pamięci, mogą ją odczytywać, ponownie zapisywać itd. Ale możesz zbudować model aktora na podstawie modelu wątkowego i faktycznie wszystkie implementacje aktorów mają wątki pod spodem. Zhakowałem coś takiego (bardzo źle), dając każdemu wątkowi kolejkę strzeżoną przez muteks - dla zabawy. Aby dowiedzieć się, jak zarządza się impedancją aktora, zobacz moje pytanie sprzed roku .
Czy mogę używać modelu aktora w dowolnym języku, używając wątków w inny sposób?
Tak, ale zajmie to trochę więcej pracy. Twój ulubiony język może mieć bibliotekę przekazywania wiadomości, więc byłaby to pierwsza rzecz do zbadania. Należy również zbadać użycie niezmiennych struktur danych. Zwróć uwagę, że jeśli struktura danych jest niezmienna, to zasadniczo rozwiązałeś problem ze stanem współdzielonym - wiele wątków może przechowywać odwołania do niezmiennych danych bez żadnych złych zdarzeń. Jest powód, dla którego języki aktorskie są również językami funkcjonalnymi (erlang, scala).
Możesz również rzucić okiem na pamięć transakcyjną oprogramowania, która jest innym, ale także atrakcyjnym modelem. Clojure to mój ulubiony przykład.
Nie powiedziałbym, że aktorzy zawsze przekazują komunikaty asynchronicznie - to byłoby zbyt wolne. Przykładowo, projekt JActor używa dwukierunkowych komunikatów (żądanie / odpowiedź), aby lepiej modelować wywołanie metody. Większość żądań jest obsługiwana synchronicznie.
JActor (biblioteka Java) również nie używa blokad. Tylko niektóre atomowe i współbieżne struktury danych, z wrzuconymi kilkoma semaforami. Przekazywanie wiadomości to około 0,8 miliarda wiadomości na sekundę.
https://github.com/laforge49/JActor
źródło