2012-01-24 16 views
17

Jak rozumiem, aktorzy to w zasadzie lekkie wątki zaimplementowane na wątkach, działające na wielu aktorów w małej puli współużytkowanych wątków.aktorzy scala vs wątki i blokowanie IO

W tym przypadku użycie operacji blokowania w aktoru blokuje wątek podstawowy. To nie jest problem z poprawnością, ponieważ biblioteka aktorów spowoduje pojawienie się kolejnych wątków w razie potrzeby (czy to prawda?), Ale potem kończy się z mnóstwem wątków, negując korzyści z używania aktorów w pierwszej kolejności.

Biorąc pod uwagę to, w jaki sposób działają aktorzy, gdy trzeba wykonywać takie operacje IO? Czy istnieją operacje, które "blokują aktor", zawieszając aktora, jednocześnie pozwalając wątkowi przejść do innych operacji (tak jak operacje blokujące zawieszają wątek, pozwalając procesorowi przejść do innych operacji), lub wszystko jest napisane w CPS, z łańcuchem aktorzy? Czy aktorzy po prostu nie pasują do tego rodzaju długotrwałej operacji?

Tło: Mam doświadczenie w pisaniu tekstów wielowątkowych w klasyczny sposób i rozumiem prettywell jak działają pętle CPS/zdarzeń, ale nie mam absolutnie żadnego doświadczenia w pracy z aktorami i po prostu chcę zrozumieć, na wysokim poziomie, jak one pasują , zanim zanurzę się w kodzie.

+1

Powinno to obejmować w pewnym momencie ograniczoną kontynuację, jak w http://jim-mcbeath.blogspot.com/2010/09/scala-coroutines.html. A może za pomocą nieblokującego przepływu komunikatów? (http://blog.typesafe.com/non-blocking-message-flow-with-akka-actors) – VonC

+0

Proszę zobaczyć moją odpowiedź tutaj http://stackoverflow.com/questions/1512066/is-there-any-non -blokowanie-io-open-source-implementacja-dla-scalas-aktorów –

Odpowiedz

2

To nie jest problem poprawności, ponieważ biblioteka aktor będzie tarło więcej wątków, jak to konieczne (tak?)

O ile rozumiem, że nie jest w porządku. Aktor jest zablokowany, a wysłanie do niego kolejnej wiadomości powoduje, że wiadomość zostanie umieszczona w skrzynce pocztowej dla aktorów, dopóki ten aktor nie będzie mógł wysłać do niej wiadomości.

W Programowaniu w Scali (1) wyraźnie stwierdza, że ​​aktorzy nie powinni blokować. Jeśli aktor musi zrobić coś długiego, powinien przekazać pracę drugiemu aktorowi, aby główny aktor mógł się uwolnić i przeczytać więcej wiadomości ze swojej skrzynki pocztowej. Gdy robotnik zakończy pracę, może zasygnalizować ten fakt z powrotem do głównego aktora, który może dokończyć robiąc cokolwiek musi.

Ponieważ pracownicy również mają skrzynki pocztowe, w efekcie pojawi się kilku pracowników, którzy pracowicie wykonują swoją pracę. Jeśli nie masz wystarczająco dużo procesora, aby to obsłużyć, ich kolejki będą po prostu coraz większe. Ostatecznie możesz skalować za pomocą zdalnych aktorów. Akka może być bardziej przydatny w takich przypadkach.

(1) Rozdział 32.5 Programowanie w Scala (Odersky, wydanie drugie, 2010)

EDIT: Znalazłem to:

Sposób scheduler o cechy aktora może być zmienione do zwróci ResizableThreadPoolScheduler, który zmienia rozmiar puli wątków, aby uniknąć głodu spowodowanego przez podmioty, które wywołują arbitralne metody blokowania.

Znaleziono go pod adresem: http://www.scala-lang.org/api/current/scala/actors/Actor.html

So, czyli w zależności od planującego impl ustawić, może basen służy do uruchamiania aktorów zostanie zwiększona. Myliłem się, kiedy powiedziałem, że się mylisz :-) Reszta odpowiedzi nadal jest prawdziwa.

1

Jak działa w serwisie erlang, że cała operacja blokowania powinna zostać wykonana przez wysłanie wiadomości, ponieważ gdy Twój aktor jest zablokowany, czekając na wiadomość, przekazuje wątek innemu aktorowi.

Więc jeśli chcesz wykonać operację blokującą, taką jak odczyt z pliku, powinieneś zrobić aktora FileReadera, który używa api Non-bloking do odczytu i zapisu z pliku. I niech twój drugi aktor użyje tego aktora (wyślij i otrzymasz do niego wiadomość) jako api do odczytu i zapisu do pliku.