maxWorkerThreads, maxIoThreads...

di Andrea Zani, in .NET,

In un mio blog precedente avevo parlato del numero di thread disponibili per l'elaborazione delle richieste per le pagine asp.net. Infatti, il numero di pagine che può elaborare contemporaneamente il Framework non è infinito, anzi, di base è abbastanza limitato: 20 su XP e 25 su 2003. Per vedere questi limiti è sufficiente leggere in machine.confi la sezione ProcessModel:

<processModel
    enable="true"
    timeout="Infinite"
    idleTimeout="Infinite"
    shutdownTimeout="0:00:05"
    requestLimit="Infinite"
    requestQueueLimit="5000"
    restartQueueLimit="10"
    memoryLimit="60"
    webGarden="false"
    cpuMask="0xffffffff"
    userName="machine"
    password="AutoGenerate"
    logLevel="Errors"
    clientConnectedCheck="0:00:05"
    comAuthenticationLevel="Connect"
    comImpersonationLevel="Impersonate"
    responseDeadlockInterval="00:03:00"
    <u>maxWorkerThreads="20"</u>
    <u>maxIoThreads="20"</u> />

Inoltre, non impostati, sono presenti:

minFreeThreads="[count]" - minimum number of free thread to allow execution of new requests.
minLocalRequestFreeThreads="[count]" - minimum number of free thread to allow execution of new local requests.

Info per queste informazioni si trovano qui.

L'impostazione di base (qui sopra preso da Windows XP Pro), è 20. Cosa vuol dire questo? Che sarà possibile elaborare al massimo 20 pagine contemporaneamente. Eventuali altre richieste rimarranno in coda in attesa che si liberino dei thread. Come detto nel blog precedente, anche eventuali chiamate con il BeginInvoke dei delegate consumiamo questi thread. Ecco una prova per vedere questo limite:

void Page_Load()
{
   int numThreads=22;
   ElencoThread[] elenco=new ElencoThread[numThreads];
   for (int i = 0; i < numThreads; i++)
   {
    elenco[i]=new ElencoThread(new Richiama(this.RichiamoReale));
    elenco[i].Ritorno=elenco[i].Thread.BeginInvoke(elenco[i],null,null);
   }
   for (int i = 0; i < numThreads; i++)
   {
    elenco[i].Thread.EndInvoke(elenco[i].Ritorno);
    elenco[i].Fine=DateTime.Now;
   }
   for (int i = 0; i < numThreads; i++)
    Label1.Text+=string.Format("N. {0} - {1} - {2}<br />",
     i,elenco[i].Inizio,elenco[i].Fine);
}

Gli oggetti utilizzati in questo codice sono la classe "ElencoThread", il delegate "Richiama" e la funzione "RichiamoReale":

delegate void Richiama(ElencoThread thread);
 public class ElencoThread
 {
  Richiama _Richiama;
  IAsyncResult _iasyncresult;
  DateTime _inizio,_fine;
  internal ElencoThread(Richiama c)
  {
   _Richiama=c;
  }
  internal Richiama Thread
  {
   get { return _Richiama; }
  }
  internal IAsyncResult Ritorno
  {
   get { return _iasyncresult; }
   set { _iasyncresult=value; }
  }
  internal DateTime Fine
  {
   get { return _fine; }
   set { _fine=value; }
  }
  internal DateTime Inizio
  {
   set { _inizio=value; }
   get { return _inizio; }
  }
 }

public void RichiamoReale(ElencoThread thread)
{
 thread.Inizio=DateTime.Now;
 Thread.Sleep(20000);
 return;
}

Questo codice non fa altro che richiamare 21 volte un delegate asincrono memorizzando l'ora d'inizio e di fine e visualizzare il risultato. Ecco un breve scorcio del risultato:

N. 1 - 20/12/2004 16.16.17 - 20/12/2004 16.16.37
N. 2 - 20/12/2004 16.16.17 - 20/12/2004 16.16.37
N. 6 - 20/12/2004 16.16.18 - 20/12/2004 16.16.38
N. 7 - 20/12/2004 16.16.19 - 20/12/2004 16.16.39
N. 13 - 20/12/2004 16.16.22 - 20/12/2004 16.16.42
N. 14 - 20/12/2004 16.16.22 - 20/12/2004 16.16.42
N. 17 - 20/12/2004 16.16.24 - 20/12/2004 16.16.44
N. 19 - 20/12/2004 16.16.25 - 20/12/2004 16.16.45
N. 20 - 20/12/2004 16.16.37 - 20/12/2004 16.16.57
N. 21 - 20/12/2004 16.16.37 - 20/12/2004 16.16.57

Il primo delegate asincrono viene richiamato alle 16.16.17, così fino a salire, per normali tempi di elaborazione, fino al diciannovesimo. Il ventesimo viene richiamato solo quando il primo ha concluso le sue operaziono non essendoci più thread disponibili (si ricorda il limite dei 20?), e infatti se si nota l'ora di fine del primo thread è esattamente l'ora 16.16.37.

Ci si può chiedere perché già del ventesimo e non dal ventunesimo l'attesa per la liberazione di un thread. Il mistero è di semplice soluzione: la pagina elaborata richiede un thread.

Ma quali sono i valori consigliati per le impostazioni del numero di thread? Purtroppo è impossibile inserire un valore superiore a 100. Sulla documentazione della Microsoft vengono consigliati in maxWorkerThreads e MaxIoThreads il valore "100" e in "minFreeThreads" un valore di 88*[numero di CPU] e in "minLocalRequestFreeThreads" a 76*[numero di CPU].

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese