2014-05-01 15 views
9

Niedawno przeczytałem o Quasar który zapewnia „lekki”/Go-like „trybu” wątki na JVM (posiada również inspirowany systemem aktora Erlang jak Akka ale nie jest to główne pytanie)Lekkie wątki w Akce

na przykład:

package jmodern; 

import co.paralleluniverse.fibers.Fiber; 
import co.paralleluniverse.strands.Strand; 
import co.paralleluniverse.strands.channels.Channel; 
import co.paralleluniverse.strands.channels.Channels; 

public class Main { 
    public static void main(String[] args) throws Exception { 
     final Channel<Integer> ch = Channels.newChannel(0); 

     new Fiber<Void>(() -> { 
      for (int i = 0; i < 10; i++) { 
       Strand.sleep(100); 
       ch.send(i); 
      } 
      ch.close(); 
     }).start(); 

     new Fiber<Void>(() -> { 
      Integer x; 
      while((x = ch.receive()) != null) 
       System.out.println("--> " + x); 
     }).start().join(); // join waits for this fiber to finish 
    } 
} 

o ile mi zrozumieć powyższy kod nie tarło żadnych wątków JVM/kernel, wszystko odbywa się w wątkach trybu użytkownika (lub tak twierdzą), który ma być tańsze (tylko lubię rutynowo, jeśli dobrze rozumiem)

Moje pytanie jest takie - o ile rozumiem, w Akka wszystko jest nadal oparte na wątkach JVM, które w większości przypadków są mapami do natywnych wątków jądra systemu operacyjnego (np. pthreads w systemach POSIX), np. według mojego zrozumienia nie ma wątków trybu użytkownika/idą jak rutyny/lekkie wątki w Akka, czy dobrze rozumiałem?

Jeśli tak, to czy wiesz, że jest to wybór projektu? A może planujesz lekkie nici w Akka w przyszłości?

Rozumiem, że jeśli masz milion aktorów, ale większość z nich blokuje, to Akka może sobie z tym poradzić za pomocą znacznie mniej fizycznych wątków, ale jeśli większość z nich nie blokuje się i nadal potrzebujesz reakcji z systemu (np. usługi milionów małych wniosków o przesyłanie strumieniowe niektórych danych), wtedy widzę zalety implementacji wątków w trybie użytkownika, co pozwala na utrzymanie wielu "wątków" przy niższym koszcie tworzenia przełączania i kończenia (oczywiście jedyną korzyścią jest równomiernie rozdzielając czas reakcji dla wielu klientów, ale czas reakcji jest nadal ważny)

Czy moje zrozumienie jest poprawne? Proszę popraw mnie jeżeli się mylę.

* Mogę być całkowicie mylące wątków trybu użytkownika GO/Co-rutyny i lekkich wątków, pytanie powyżej opiera się na mojej biednej zrozumienia, że ​​są one jednym z taka sama.

+1

To jest to, co pamiętam z mojego doświadczenia z Pythonem. I nie jest to bezpośrednia odpowiedź, ale może być przydatna. Zarówno użytkownicy/lekkie wątki, jak i rzeczywiste wątki systemowe mają swoje zastosowania. Sprowadza się do tego, oba zapewniają współbieżność, ale tylko wątki systemowe zapewniają równoległość. Więc jeśli wykonujesz ciężkie obliczenia, nie otrzymasz żadnego wsparcia od używania wątków użytkownika, ale będziesz od wątków systemowych. W innej sytuacji, w której masz tylko jeden rdzeń procesora, a chcesz serwera, używanie wątków użytkownika jest jedynym rozwiązaniem. – Andrey

+0

Tak, to też rozumiem, np. wątki użytkownika są dobre tylko dla zapewnienia "dobrego wykorzystania" procesora, np. przełączanie między 2 wątkami użytkownika, które czasami blokują IO są tańsze niż używanie pełnego wątku. nie uzyskujesz paralelizmu, ale masz lepsze wykorzystanie procesora, jeśli dobrze zrozumiałem. –

+0

Proszę spojrzeć na moją odpowiedź, może to być pomocne: http://stackoverflow.com/questions/29680718/relinquish-the-thread -cpu-until-async-call-completes-in-akka-and-java/29748613 # 29748613 – circlespainter

Odpowiedz

8

Akka jest bardzo elastyczny biblioteki i pozwala zaplanować aktorów użyciu (w istocie sprowadza się do tego poprzez łańcuch cech) zwykłą cechą ExecutionContext, która, jak widać, akceptuje Runnable S i jakoś wykonuje im. Tak więc, o ile widzę, możliwe jest, że można napisać powiązanie z czymś takim jak Quasar i użyć go jako "zaplecza" dla aktorów Akka.

Jednak biblioteki Quasar i podobne prawdopodobnie zapewnią specjalne narzędzia do komunikacji między włóknami. Nie wiem też, jak poradziliby sobie z blokowaniem zadań takich jak I/O, prawdopodobnie mieliby również taki mechanizm. Nie jestem pewien, czy dzięki temu Akka będzie mogła poprawnie działać na zielonych nitkach. Quasar zdaje się również opierać na instrumentacji kodu bajtowego i jest to dość zaawansowana technika, która może mieć wiele implikacji, uniemożliwiając jej tworzenie kopii Akki.

Nie należy jednak martwić się lekkością nici podczas korzystania z aktorów Akka. W rzeczywistości Akka jest w stanie stworzyć miliony aktorów w jednym systemie (zob. here), a wszyscy ci aktorzy będą działali dobrze.

Osiąga się to poprzez sprytne szeregowanie w specjalnych rodzajach pul wątków, takich jak puli wątków łączenia widełek. Oznacza to, że jeśli aktorzy nie są zablokowani w przypadku długotrwałych obliczeń, mogą przeszukiwać wiele wątków znacznie mniej niż liczba tych aktorów. Na przykład możesz utworzyć pulę wątków, która będzie używać maksymalnie 8 wątków (po jednym dla każdego rdzenia procesora 8-rdzeniowego), a wszystkie działania aktorów będą zaplanowane na te wątki.

Elastyczność Akka pozwala na skonfigurowanie dokładnego dyspozytora, który będzie wykorzystywany przez określonych aktorów, jeśli będzie potrzebny. Możesz tworzyć dedykowanych dyspozytorów dla aktorów, którzy pozostają w długotrwałych zadaniach, takich jak dostęp do bazy danych. Aby uzyskać więcej informacji, patrz here.

Krótko mówiąc, nie, nie potrzebujesz nici użytkownika dla aktorów, ponieważ aktorzy nie odwzorowują pojedynczych wątków na natywne (chyba że jesteś wymuszają na nich, ale to powinno unikać za wszelką cenę).

+0

Mniej wątków - mniej przełączników kontekstu z tym samym opóźnieniem. Krótko mówiąc, możesz rozważyć użycie wątków użytkownika, jeśli możesz. –

+0

"Osiąga się to poprzez sprytne szeregowanie w specjalnych rodzajach pul wątków" <- Gdzie mogę uzyskać więcej informacji o tym, jak to się robi (w najprostszej formie)? – Franz

+0

@Franz Nie jestem pewien co do najprostszej formy, ale możesz zacząć od czytania [o dyspozytorach] (http://doc.akka.io/docs/akka/2.4/scala/dispatchers.html) w akka docs, a następnie przejdź bezpośrednio do dokumentacji dla puli wątków [fork-join thread] (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html). Możesz także wypróbować w Google o pulach wątków join-join, znajdziesz wiele samouczków i wyjaśnień. –

2

Akka aktorzy są zasadniczo asynchroniczny i dlatego można mieć wiele z nich, podczas gdy aktorzy Quasar (tak, Quasar oferuje realizację aktorów też), które są bardzo zbliżone do Erlang, przedstawiają synchroniczny lub blokowanie, ale używają włókien, a nie Java (tj. W obecnych systemach operacyjnych), więc nadal możesz mieć ich dużo z taką samą wydajnością jak async, ale styl programowania jest równie prosty, jak podczas używania zwykłych wątków i blokowania połączeń.

I/O jest obsługiwane poprzez integrację: Quasar includes a framework to convert both async and sync APIs into fiber-blocking i Comsat zawierają wiele takich integracji już (jeden z Java NIO jest zawarty bezpośrednio w Quasar).

My reply to another question zawiera dalsze informacje.