Jak działają aktorzy w porównaniu z wątkami?

88

Czy jest jakieś dobre i krótkie wyjaśnienie, jak działają aktorzy w porównaniu z wątkami?

Czy wątek nie może być postrzegany jako aktor i wysyłać wiadomości do innych wątków? Widzę pewną różnicę, ale nie jest to dla mnie takie jasne. Czy mogę używać aktorów w dowolnym języku, używając wątków w inny sposób?

Jonas
źródło

Odpowiedzi:

78

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.

Rob Lachlan
źródło
3
Im częściej używam modeli współbieżności opartych na asynchronicznym przekazywaniu komunikatów (np. Aktorzy lub async / await), tym bardziej myślę, że są one po prostu podwójne w stosunku do starego, standardowego modelu współbieżności blokowania synchronicznego. Asynchroniczne przekazywanie wiadomości nie jest tak naprawdę łatwiejsze ani trudniejsze niż używanie blokad i monitorów. Rzeczywiście, nie ma wspólnego stanu zmiennego, ale tylko na poziomie jednego aktora . Ale aktor wciąż ma zmienny stan i jest faktycznie obserwowalny przez wszystkich aktorów, którzy z nim współpracują. W związku z tym możesz mieć te same problemy: impas, livelocks, głód, warunki wyścigu itp.
Piotr Kołaczkowski
2

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

Bill la Forge
źródło
2
Model aktora jest definiowany wyłącznie przy użyciu komunikacji asynchronicznej ( en.wikipedia.org/wiki/Actor_model ). Jeśli JActor tego nie robi, to nie jest to w 100% tylko model aktora. Może po prostu używać modelu aktora jako jednej z wielu jego cech.
BT,