2016-02-22 11 views
5

Non sono sicuro che questo si riferisca più ad akka.net o TPL, ma userò gli attori per il mio esempio per chiarire la domanda.Attiva più thread istantaneamente su akka.net

La domanda in breve: esiste un modo per dire a akka.net di attivare più thread contemporaneamente rispetto a quelli che effettivamente dispongono di core CPU? Ecco il codice di esempio ei dettagli:

Attualmente sto utilizzando un laptop con un processore a 8 core. Quindi diciamo che sto creando 20 attori:

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

E poi sto passando un messaggio a tutti coloro:

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); 

Tutto l'attore fa, mentre riceve il messaggio è il seguente falso processo di lunga esecuzione:

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); 

ho anche questo codice nel suo costruttore, in modo che io so quando l'attore è effettivamente creato:

Così ora quando eseguo l'applicazione, per prima cosa ottengo la linea "inviato al messaggio dell'attore" per tutti e 20 gli attori - nello stesso millesimo di secondo. Ma in seguito, quando arriva il momento dell'inizializzazione, ciò che accade è che inizialmente vengono creati solo 8 attori.

Quindi, poiché nessuno degli altri attori ha terminato il lavoro, ESATTAMENTE 1 secondo dopo, ne viene inizializzato un altro (il 9). Un altro secondo dopo, abbiamo creato il nostro 10 ° attore e avviato l'operazione Thread.Sleep.

Ora la domanda è, c'è un modo per dire akka.net (o alla TPL sotto di esso) che sono sicuro che i thread attenderanno ~ 60 secondi per ogni chiamata di servizio? In modo che tutti i 20 thread vengano attivati ​​contemporaneamente, invece di avviare 8 in una sola volta e che i 20 thread completi vengano eseguiti solo dopo 12 secondi?

risposta

3

Gli attori Akka vengono eseguiti su .Net ThreadPool per impostazione predefinita.

Si verifica un esaurimento threadPool in cui sono occupati tutti i thread disponibili (uno per CPU). Quando tutti i suoi thread sono occupati, il ThreadPool aggiunge un altro thread al secondo al suo pool.

Per "risolvere" il problema è possibile aumentare il numero minimo di thread con ThreadPool.SetMinThreads. Ma la vera soluzione è non bloccare i thread (e non bloccare gli attori).

Se il carico di lavoro è vincolato dalla CPU, non sarà più rapido eseguire più attori contemporaneamente.

Se il carico di lavoro è legato IO, si dovrebbe chiamare in modo asincrono:

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

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

Grazie. Sfortunatamente alcuni client vogliono impostazioni di conteggio thread esplicite, ma per chiunque stia leggendo questo, che non è vincolato dai requisiti, suggerisco di seguire il percorso asincrono. Testati entrambi, tutto funziona perfettamente. – nikovn