Maksymalna liczba wątków w aplikacji .NET?


140

Jaka jest maksymalna liczba wątków, które można utworzyć w aplikacji C #? A co się stanie, gdy osiągniesz ten limit? Czy rzucono jakiś wyjątek?


Odpowiedź będzie inna, jeśli korzystasz z maszyny wirtualnej x64 lub maszyny wirtualnej x86
Brian R. Bondy

W mojej sytuacji jest to x86, ale czy możesz udzielić odpowiedzi na oba pytania na wypadek, gdyby ktoś tego potrzebował?

Odpowiedzi:


145

Nie ma żadnych ograniczeń. Maksymalna liczba wątków zależy od ilości dostępnych zasobów fizycznych. Szczegółowe informacje można znaleźć w artykule Raymonda Chena .

Jeśli chcesz zapytać, jaka jest maksymalna liczba wątków, prawdopodobnie robisz coś nie tak.

[ Aktualizacja : Po prostu nie interesuje nas: domyślne liczby wątków puli wątków .NET:

  • 1023 w Framework 4.0 (środowisko 32-bitowe)
  • 32767 w Framework 4.0 (środowisko 64-bitowe)
  • 250 na rdzeń w Framework 3.5
  • 25 na rdzeń w Framework 2.0

(Te liczby mogą się różnić w zależności od sprzętu i systemu operacyjnego)]


13
Jak to wymyśliłeś? Czy wiesz, czym jest .NET 4.5 lub co będzie 5.0?
goodguys_activate

3
Możesz użyć tego kodu, aby uzyskać liczby: int workerThreads; int completePortThreads; ThreadPool.
JALLRED

1
@MitchWheat Zastanawiałem się sam, ponieważ powiązany artykuł nie dotyczy .NET, ale zwykłego 'ol C.
pqsk

1
@LoukMo: jeśli nie możesz utworzyć wątku, prawdopodobnie zabrakło Ci pamięci! Nie próbowałem tego, ale zakładam, że wyjątek pamięci zostanie wyrzucony ....?
Mitch Wheat

1
@Liam Link powinien teraz zostać naprawiony.
Eugene Komisarenko

26

Mitch ma rację. To zależy od zasobów (pamięci).

Chociaż artykuł Raymonda jest poświęcony wątkom systemu Windows, a nie wątkom C #, logika dotyczy tego samego (wątki C # są mapowane na wątki systemu Windows).

Jednak, tak jak w C #, jeśli chcemy być całkowicie precyzyjni, musimy rozróżnić wątki „rozpoczęte” i „nie rozpoczęte”. Tylko rozpoczęte wątki faktycznie rezerwują miejsce na stosie (jak mogliśmy się spodziewać). Wątki nierozpoczęte alokują tylko informacje wymagane przez obiekt wątku (możesz użyć reflektora, jeśli jesteś zainteresowany rzeczywistymi składnikami).

Możesz to przetestować samodzielnie, porównaj:

    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)
        {
        }
    }

z:

   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)
        {
        }
    }

Umieść punkt przerwania w wyjątku (oczywiście z pamięci) w VS, aby zobaczyć wartość licznika. Oczywiście istnieje bardzo znacząca różnica.


9

Zrobiłem test na systemie 64-bitowym z konsolą C #, wyjątkiem jest rodzaj braku pamięci, przy użyciu 2949 wątków.

Zdaję sobie sprawę, że powinniśmy używać puli wątków, co robię, ale ta odpowiedź jest odpowiedzią na główne pytanie;)


6

Powinieneś używać puli wątków (lub asynchronicznych delgates, które z kolei używają puli wątków), aby system mógł zdecydować, ile wątków ma zostać uruchomionych.


Odpowiedź brzmi: pozwól systemowi zdecydować.
Ian Boyd,

@Ian: Głosowałem na ciebie niżej, ponieważ ta sama odpowiedź została udzielona dziewięć miesięcy wcześniej.
John Saunders

11
Połączyć. nie widzę żadnej wzmianki o puli wątków jako niczyjej odpowiedzi.
Ian Boyd

4

Jeff Richter w CLR przez C #:

„W wersji 2.0 środowiska CLR maksymalna liczba wątków roboczych wynosi domyślnie 25 na procesor w maszynie, a maksymalna liczba wątków we / wy wynosi domyślnie 1000. Limit 1000 w rzeczywistości nie ma żadnego ograniczenia”.

Zauważ, że jest to oparte na .NET 2.0. Mogło się to zmienić w .NET 3.5.

[Edytuj] Jak zauważył @Mitch, jest to specyficzne dla puli wątków CLR. Jeśli tworzysz wątki bezpośrednio, zobacz komentarze @Mitch i innych.


W swoim komentarzu na temat .NET 3.5 mylisz środowiska CLR 2.0 i .NET 2.0.
bzlm

O ile wiem, dodatek SP1 dla .NET 2.0 (część .NET 3.5) zmienił domyślne wątki robocze na 250 na procesor / rdzeń dla pul wątków.
Michael Damatov

0

Możesz to przetestować , używając tego skróconego kodu:

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

Uważaj na 32-bitowe i 64-bitowe tryby aplikacji.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.