Numero massimo di thread in un'app .NET?


140

Qual è il numero massimo di thread che è possibile creare in un'applicazione C #? E cosa succede quando si raggiunge questo limite? Viene generata un'eccezione di qualche tipo?


La risposta sarà diversa se si esegue su VM x64 o VM x86
Brian R. Bondy,

Nella mia situazione è x86, ma puoi fornire la risposta per entrambi nel caso in cui qualcun altro ne abbia bisogno?

Risposte:


145

Non esiste un limite intrinseco. Il numero massimo di thread è determinato dalla quantità di risorse fisiche disponibili. Vedi questo articolo di Raymond Chen per dettagli.

Se devi chiedere qual è il numero massimo di thread, probabilmente stai facendo qualcosa di sbagliato.

[ Aggiornamento : solo per interesse: numero di thread predefiniti del pool di thread .NET:

  • 1023 in Framework 4.0 (ambiente a 32 bit)
  • 32767 in Framework 4.0 (ambiente a 64 bit)
  • 250 per core in Framework 3.5
  • 25 per core in Framework 2.0

(Questi numeri possono variare a seconda dell'hardware e del sistema operativo)]


13
Come l'hai capito? Sai cos'è .NET 4.5 o quale sarà 5.0?
goodguys_activate il

3
È possibile utilizzare questo codice per ottenere i conteggi: int workerThreads; int completamentoPortThreads; ThreadPool.GetMaxThreads (out workerThreads, out completamentoPortThreads);
JALLRED

1
@MitchWheat Mi stavo chiedendo, perché l'articolo collegato non parla di .NET, ma semplicemente 'ol C.
pqsk il

1
@LoukMo: se non riesci a creare un thread, probabilmente hai esaurito la memoria! Non l'ho provato, ma presumo che verrà generata un'eccezione di memoria ....?
Mitch Wheat

1
@Liam Il collegamento ora dovrebbe essere corretto.
Eugene Komisarenko,

26

Mitch ha ragione. Dipende dalle risorse (memoria).

Sebbene l'articolo di Raymond sia dedicato ai thread di Windows, non ai thread C #, la logica si applica allo stesso modo (i thread C # sono associati ai thread di Windows).

Tuttavia, poiché siamo in C #, se vogliamo essere completamente precisi, dobbiamo distinguere tra thread "avviati" e "non avviati". Solo i thread avviati in realtà riservano spazio nello stack (come potevamo aspettarci). I thread non avviati allocano solo le informazioni richieste da un oggetto thread (è possibile utilizzare il riflettore se interessati ai membri effettivi).

Puoi effettivamente testarlo da solo, confrontare:

    static void DummyCall()
    {
        Thread.Sleep(1000000000);
    }

    static void Main(string[] args)
    {
        int count = 0;
        var threadList = new List<Thread>();
        try
        {
            while (true)
            {
                Thread newThread = new Thread(new ThreadStart(DummyCall), 1024);
                newThread.Start();
                threadList.Add(newThread);
                count++;
            }
        }
        catch (Exception ex)
        {
        }
    }

con:

   static void DummyCall()
    {
        Thread.Sleep(1000000000);
    }

    static void Main(string[] args)
    {
        int count = 0;
        var threadList = new List<Thread>();
        try
        {
            while (true)
            {
                Thread newThread = new Thread(new ThreadStart(DummyCall), 1024);
                threadList.Add(newThread);
                count++;
            }
        }
        catch (Exception ex)
        {
        }
    }

Inserisci un breakpoint nell'eccezione (memoria insufficiente, ovviamente) in VS per vedere il valore del contatore. C'è una differenza molto significativa, ovviamente.


9

ho fatto un test su un sistema a 64 bit con console c #, l'eccezione è il tipo di memoria insufficiente, usando 2949 thread.

Mi rendo conto che dovremmo usare il pool di threading, cosa che faccio, ma questa risposta è in risposta alla domanda principale;)


6

Dovresti usare il pool di thread (o i delegati asincroni, che a loro volta utilizzano il pool di thread) in modo che il sistema possa decidere quanti thread devono essere eseguiti.


La risposta è lasciare che il sistema decida.
Ian Boyd,

@Ian: ti ho sottovalutato perché la stessa risposta era stata data nove mesi prima.
John Saunders,

11
Link. non vedo alcuna menzione del thread pool come la risposta di nessuno.
Ian Boyd,

4

Jeff Richter in CLR via C #:

"Con la versione 2.0 del CLR, il numero massimo di thread di lavoro è impostato automaticamente su 25 per CPU nella macchina e il numero massimo di thread di I / O è impostato automaticamente su 1000. Un limite di 1000 non è effettivamente un limite."

Nota che si basa su .NET 2.0. Questo potrebbe essere cambiato in .NET 3.5.

[Modifica] Come sottolineato da @Mitch, questo è specifico per il ThreadPool CLR. Se stai creando discussioni vedi direttamente i commenti di @Mitch e di altri.


Stai confondendo CLR 2.0 e .NET 2.0 nel tuo commento su .NET 3.5.
bzlm,

Per quanto ne so, SP1 per .NET 2.0 (parte di .NET 3.5) ha modificato i thread di lavoro predefiniti in 250 per CPU / core per pool di thread.
Michael Damatov,

0

Puoi testarlo usando questo codice snipped:

private static void Main(string[] args)
{
   int threadCount = 0;
   try
   {
      for (int i = 0; i < int.MaxValue; i ++)
      {
         new Thread(() => Thread.Sleep(Timeout.Infinite)).Start();
         threadCount ++;
      }
   }
   catch
   {
      Console.WriteLine(threadCount);
      Console.ReadKey(true);
   }
}

Attenzione alle modalità di applicazione a 32 e 64 bit.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.