Czy mój opis modelu aktora jest prawidłowy?

13

Jeśli rozumiem, model aktora jest podobny do modelu obiektowego, ale z kilkoma różnicami:

  1. KAŻDY obiekt spawnuje swój własny wątek i nie stanowi problemu, nawet jeśli masz tysiące obiektów.
  2. Aktorzy nie wchodzą w interakcje, wywołując funkcje i zwracając wartości, ale zamiast tego wysyłając i odbierając wiadomości.
  3. Jeśli nie naruszysz tego modelu, Twoja aplikacja będzie korzystała z pełnej współbieżności bez ryzyka warunków wyścigowych.
  4. Wszystko, co możesz zrobić w OO, możesz zrobić z aktorami, ale lepiej, problem polega na tym, że wszystko, co zakodowaliśmy w ostatnich latach, było oparte na OO - ale przejście jest nieuchronne.

Załóżmy na przykład, że muszę zdefiniować klasę / aktora wektora 3d, utworzyć dwie instancje i wywołać na nich operację sumowania.

OBIEKT ZORIENTOWANY:

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

MODEL AKTORA:

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
}

Czy to to? Czy też całkowicie się mylę?

WindScar
źródło
Lekcy aktorzy, mikroagenty lub komponenty przepływu danych niekoniecznie używają własnego wątku. :-) Sprawdź następujące terminy: programowanie aktorskie, programowanie agentowe, programowanie przepływem danych. Są bardzo podobne, ale mają różne ograniczenia. Och, zadam to pytanie ;-)
inf3rno

Odpowiedzi:

12

Krótka odpowiedź brzmi: nie, to nieprawda.

  1. zaczyna się w miarę poprawnie (każdy aktor przynajmniej potencjalnie wykonuje jako niezależny wątek), ale potem w dużej mierze znika z szyn. W modelu nie ma nic, co sprawia, że ​​wiele wątków działa dobrze - to zależy od implementacji. Co najwyżej łatwość tworzenia dużej liczby wątków wywiera presję na implementację w celu zapewnienia wydajnego wątkowania. Przynajmniej jeśli chodzi o model, wszelkie podobieństwo między aktorami a przedmiotami jest w większości przypadkowe. „Obiekt” niesie ze sobą dość konkretne implikacje dotyczące sposobu łączenia kodu i danych. Aktor na ogół będzie zawierał zarówno kod, jak i dane, ale niewiele sugeruje, w jaki sposób są one łączone (poza faktem, że jedynymi danymi widocznymi dla świata zewnętrznego są wiadomości).

  2. Zazwyczaj opisywanie interakcji to wysyłanie wiadomości, tak. Nie mam przydatnego cytatu, ale ktoś już dawno udowodnił, że mechanizmy takie jak funkcje wirtualne C ++ są izomorficzne w wysyłaniu wiadomości (ponieważ funkcje wirtualne są zwykle implementowane, używasz przesunięcia w vtable - ale jeśli zamiast tego wysłał przesunięcie do tabeli komunikatów, efekt byłby taki sam).

  3. To nie jest takie proste. Jeśli potrafisz znaleźć kopię, Henry Baker (z kimś, kogo obecnie nie pamiętam) napisał artykuł o zasadach niezbędnych do zachowania spójności danych w modelu aktorskim.

  4. „Lepszy” jest co najwyżej wysoce subiektywny. Niektóre problemy mają charakter bardzo równoległy i naprawdę obejmują dużą liczbę zasadniczo autonomicznych jednostek, przy minimalnej interakcji, która jest przede wszystkim asynchroniczna. W takim przypadku model aktora może naprawdę działać bardzo dobrze. W przypadku innych problemów tak naprawdę nie jest. Niektóre problemy mają prawie całkowicie szeregowy charakter. Inne mogą być wykonywane równolegle, ale nadal wymagają ścisłej synchronizacji między tymi czynnościami (np. Zasadniczo tryb podobny do SIMD, w którym wykonuje się jedną instrukcję na raz, ale każda instrukcja działa na dużą liczbę elementów danych). Z pewnością możliwe jest rozwiązanie obu tych problemów za pomocą modelu aktora - ale w przypadku takich problemów często wymaga to sporo dodatkowej pracy za niewielką lub żadną korzyść.

Jerry Coffin
źródło
Nie ma związku między liczbą aktorów a liczbą wątków; model aktora gwarantuje, że dana instancja będzie obsługiwana tylko przez jeden wątek naraz, więc twoi aktorzy są już bezpieczni dla wątku i nie musisz w nich używać strategii synchronizacji i blokowania.
Rob Crawford
@RobCrawford: to jeden (dość trywialny) sposób zapewnienia spójności danych w modelu Actor. Artykuł Hewitt / Baker obejmuje więcej możliwości, takich jak wiele kopii aktora w osobnych wątkach (hmm ... patrząc na moją odpowiedź, zastanawiam się, czy naprawdę nie pamiętałem wtedy nazwiska Carla Hewitta, czy też być ironicznym, kiedy to napisałem).
Jerry Coffin
Czy asynchroniczność przekazu nie jest istotnym elementem modelu? To z pewnością zapobiegłoby jego izomorficzności z wirtualnymi wywołaniami funkcji, które mają charakter synchroniczny. Czy to rozróżnienie nie ma znaczenia z jakiejś perspektywy?
boycy
2

Odnośnie 1: Pracowałem z aplikacją modelowaną przez aktora z jednym wątkiem (ish), więc całkiem możliwe jest zignorowanie dużej liczby wątków, które to sugeruje. AFAIK, nici nie są lekkimi przedmiotami w żaden sposób, więc prawdopodobnie nie jest pożądane, aby mieć jeden dla każdego aktora, w zależności od liczby aktorów, których używasz.

Odnośnie 3: Jestem całkiem pewien, że warunki wyścigu mogą się zdarzyć w systemach modelowanych przez aktorów po prostu z powodu logiki programowania?

Odnośnie 4: Zdefiniować „lepiej”? Z mojego doświadczenia wynika, że ​​logika asynchroniczna może być znacznie trudniejsza do odczytania niż rzeczy synchroniczne. np. w powyższym przykładzie nie wiesz, która operacja jest odpowiedzialna za wynik, więc musisz wykonać dodatkowe śledzenie wiadomości. Po dodaniu i włączeniu i wyłączeniu innych komunikatów w logice intencja kodu rozłożona jest na kilka funkcji wysyłania / odbierania.

Powiedziawszy to wszystko, jestem wielkim fanem wykorzystania modelu aktora do wyższych warstw aplikacji. Może to ułatwić odsprzęganie, ponieważ dodawanie zależności jest nieco trudniejsze niż dodawanie funkcji. Nie mam też dużego doświadczenia z językiem wyższym niż języki Java, a inne paradygmaty mogą wspierać asynchroniczność w bardziej fundamentalny sposób.

holowniki
źródło
Odnośnie # 1: „wątek” może odnosić się do wielu rzeczy. Wątki systemu operacyjnego są zwykle dość ciężkie, prawda, ale istnieją środowiska wykonawcze, które wewnętrznie obsługują setki, tysiące, a nawet miliony „wątków” wykonania w niewielkiej liczbie wątków systemu operacyjnego. W niektórych implementacjach takie modele najwyraźniej skalują się do kilkudziesięciu rdzeni (widziałem stwierdzenia, że ​​najnowsze wersje GHC dobrze się bawią z 32 rdzeniami).