2016-02-22 10 views
5

Nie jestem pewien, czy to dotyczy bardziej akka.net czy TPL, ale użyję aktorów dla mojego przykładu, aby wyjaśnić pytanie.Fire multiple threads natychmiast w akka.net

Pytanie w pigułce: czy jest jakiś sposób, aby powiedzieć, że akka.net wystrzelił więcej nitek na raz, niż w rzeczywistości mam rdzenie procesora? Oto przykładowy kod i szczegóły:

Używam obecnie laptopa z procesorem 8-rdzeniowym. Więc powiedzmy, że tworzę 20 aktorów:

for (int i = 0; i < 20; i++) 
{ 
    actorList.Add(system.ActorOf<ExampleActor>()); 
} 

A potem olewam wiadomość do wszystkich tych:

actorList[0].Tell(new ExampleMessage()); 
Console.WriteLine("sent message to actor 1\t" + DateTime.Now.TimeOfDay); 
actorList[1].Tell(new ExampleMessage()); 
Console.WriteLine("sent message to actor 2\t" + DateTime.Now.TimeOfDay); 
... 
actorList[19].Tell(new ExampleMessage()); 
Console.WriteLine("sent message to actor 20\t" + DateTime.Now.TimeOfDay); 

Wszystko aktor ma, podczas odbierania wiadomości jest następująca fałszywy proces długotrwały:

Console.WriteLine("Accessing slow service\t" + DateTime.Now.TimeOfDay 
    + "\t" + Thread.CurrentThread.ManagedThreadId); 
Thread.Sleep(60000); 
Console.WriteLine("Service call was successful\t" + DateTime.Now.TimeOfDay 
    + "\t" + Thread.CurrentThread.ManagedThreadId); 

ja też mam ten kod w jej konstruktora, tak, że wiem, kiedy aktor jest rzeczywiście stworzył:

public ExampleActor() 
{ 
    Console.WriteLine("Creating " + this.Self.Path + DateTime.Now.TimeOfDay); 
    .... 
} 

Teraz, gdy uruchamiam aplikację, najpierw otrzymuję komunikat "wysłana wiadomość do aktora" dla wszystkich 20 aktorów - w tej samej milisekundie. Później, gdy nadejdzie czas inicjacji, na początku powstaje tylko 8 aktorów.

Następnie, ponieważ żaden z pozostałych aktorów nie zakończył pracy, DOKŁADNIE 1 sekundę później, inicjalizowany jest kolejny (9-ty). Kolejna sekunda później nasz dziesiąty aktor stworzył i rozpoczął operację Thread.Sleep.

Teraz pytanie brzmi, czy jest jakikolwiek sposób, aby powiedzieć stronie internetowej akka.net (lub TPL poniżej), że jestem pewien, że wątki będą czekać ~ 60 sekund na każde wezwanie serwisowe? Aby wszystkie 20 wątków zostało wystrzelonych jednocześnie, zamiast ośmiu uruchomionych jednocześnie, a całe 20 wątków uruchomionych dopiero po 12 sekundach minęło?

Odpowiedz

3

Aktorzy Akka działają domyślnie na .Net ThreadPool.

Występuje głód wątku, w którym wszystkie dostępne wątki są zajęte (po jednym na procesor). Gdy wszystkie wątki są zajęte, ThreadPool dodaje jeszcze jeden wątek na sekundę do swojej puli.

Aby "rozwiązać" problem, można zwiększyć minimalną liczbę wątków za pomocą ThreadPool.SetMinThreads. Ale prawdziwą poprawką jest nie blokowanie wątków (i nie blokowanie aktorów).

Jeśli obciążenie związane z obciążeniem procesora jest zbyt duże, nie będzie działać szybciej, aby więcej podmiotów działało jednocześnie.

Jeśli nakład pracy związany jest IO, należy nazwać asynchronicznie:

Receive<string>(msg => 
{ 
    DoSomethingAsync(msg).PipeTo(Self); 
} 

Receive<Result>(msg => 
{ 
    // Process the result 
} 
+0

Dziękuję. Niestety, niektórzy klienci oczekują jawnych ustawień liczby wątków, ale dla każdego, kto to czyta, kto nie jest związany wymaganiami, sugeruję, abyś podążał drogą asynchroniczną. Testowane oba, wszystko działa idealnie. – nikovn