.NETアプリの最大スレッド数?


140

C#アプリケーションで作成できるスレッドの最大数はいくつですか?そして、この制限に達するとどうなりますか?何らかの例外がスローされますか?


x64 VMまたはx86 VMで実行している場合、答えは異なります
ブライアンR.ボンディ

私の状況ではx86ですが、他の誰かがそれを必要とする場合に備えて、両方に答えを提供できますか?

回答:


145

固有の制限はありません。スレッドの最大数は、使用可能な物理リソースの量によって決まります。詳細については、Raymond Chenによるこの記事を参照してください。

スレッドの最大数を尋ねる必要がある場合は、おそらく何か問題があります。

[ 更新:ちょうど興味がない:.NETスレッドプールのデフォルトのスレッド数:

  • Framework 4.0の1023(32ビット環境)
  • Framework 4.0(64ビット環境)の32767
  • Framework 3.5ではコアあたり250
  • Framework 2.0ではコアあたり25

(これらの数値はハードウェアとOSによって異なる場合があります)]


13
どのようにしてこれを理解しましたか?.NET 4.5とは何か、または5.0は何かを知っていますか?
goodguys_activate

3
次のコードを使用して、カウントを取得できます:int workerThreads; int completionPortThreads; ThreadPool.GetMaxThreads(out workerThreads、out completionPortThreads);
JALLRED 2014年

1
@MitchWheat私はC.老いたリンク先の記事は、.NETを議論していないので、自分自身を不思議に思ったが、平野た
pqsk

1
@LoukMo:スレッドを作成できない場合は、おそらくメモリが不足しています!試したことはありませんが、メモリ例外がスローされると思います。
ミッチウィート

1
@Liamリンクを修正する必要があります。
Eugene Komisarenko

26

ミッチは正しいです。リソース(メモリ)に依存します。

Raymondの記事はC#スレッドではなくWindowsスレッドに特化していますが、ロジックは同じです(C#スレッドはWindowsスレッドにマップされます)。

ただし、C#を使用しているため、完全に正確にしたい場合は、「開始済み」スレッドと「未開始」スレッドを区別する必要があります。開始されたスレッドのみが実際にスタックスペースを予約します(予想通り)。開始されていないスレッドは、スレッドオブジェクトに必要な情報のみを割り当てます(実際のメンバーに関心がある場合は、リフレクターを使用できます)。

あなたは実際にそれを自分でテストすることができます、比較してください:

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

と:

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

VSの例外(もちろんメモリ不足)にブレークポイントを設定して、counterの値を確認します。もちろん、非常に大きな違いがあります。


9

私は64ビットシステムでc#コンソールを使用してテストを行いましたが、例外は2949スレッドを使用するメモリ不足のタイプです。

私はスレッドプールを使用する必要があることを理解していますが、この回答は主な質問への回答です;)


6

システムが実行するスレッドの数を決定できるように、スレッドプール(または非同期のデリゲート、つまりスレッドプールを使用)を使用する必要があります。


答え、システムに決定させることです。
Ian Boyd

@イアン:同じ回答者が9か月前に与えられたので、私はあなたに反対票を投じました。
ジョンサンダース

11
リンク。誰かの答えとしてスレッドプールについての言及はありません。
Ian Boyd

4

C#を介したCLRのJeff Richter:

「バージョン2.0のCLRでは、ワーカースレッドの最大数はデフォルトでマシンのCPUあたり25になり、I / Oスレッドの最大数はデフォルトで1000になります。1000の制限は事実上まったく制限なしです。」

これは.NET 2.0に基づいていることに注意してください。これは.NET 3.5で変更された可能性があります。

[編集] @Mitchが指摘したように、これはCLR ThreadPoolに固有のものです。スレッドを作成している場合は、@ Mitchなどのコメントを直接参照してください。


.NET 3.5に関するコメントでCLR 2.0と.NET 2.0を混同しています。
bzlm 2008年

私が知る限り、.NET 2.0のSP1(.NET 3.5の一部)は、スレッドプールのCPU /コアあたりのワーカースレッドのデフォルトを250に変更しました。
マイケル・ダマトフ2008年

0

次のコードを使用してテストできます。

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

アプリケーションの32ビットおよび64ビットモードに注意してください。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.