.NET 앱의 최대 스레드 수?


140

C # 응용 프로그램에서 만들 수있는 최대 스레드 수는 얼마입니까? 이 한계에 도달하면 어떻게됩니까? 어떤 종류의 예외가 발생합니까?


x64 VM 또는 x86 VM에서 실행중인 경우 답변이 다를 수 있습니다.
Brian R. Bondy

내 상황에서는 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, outcompletePortThreads);
JALLRED

1
@MitchWheat 링크 된 기사는 .NET에 대해서는 다루지 않고 일반 'ol C.
pqsk

1
@LoukMo : 스레드를 만들 수 없다면 메모리가 부족한 것입니다! 시도하지는 않았지만 메모리 예외가 발생한다고 가정합니다 ....?
Mitch Wheat

1
@Liam 이제 링크가 수정되었습니다.
유진 코 미사 렌코

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의 예외 (물론 메모리 제외)에 중단 점을 두어 카운터 값을 확인하십시오. 물론 매우 중요한 차이가 있습니다.


9

c # 콘솔을 사용하여 64 비트 시스템에서 테스트를 수행했지만 예외는 2949 스레드를 사용하여 메모리 부족입니다.

스레딩 풀을 사용해야한다는 것을 알고 있지만이 대답은 주요 질문에 대한 답변입니다.)


6

시스템이 실행할 스레드 수를 결정할 수 있도록 스레드 풀 (또는 스레드 풀을 사용하는 비동기 델 게이트)을 사용해야합니다.


시스템이 결정하게하는 것입니다.
Ian Boyd

@Ian : 같은 답변이 9 개월 전에 주어 졌기 때문에 나는 당신을 하향 투표했습니다.
John Saunders

11
링크. 누군가의 대답으로 스레드 풀에 대한 언급이 없습니다.
Ian Boyd

4

C #을 통한 CLR의 Jeff Richter :

"CLR 2.0 버전의 경우 최대 작업자 스레드 수는 기본적으로 시스템의 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

내가 아는 한 .NET 2.0 SP. (.NET 3.5의 일부) 작업자 스레드 기본값을 스레드 풀의 CPU / 코어 당 250으로 변경했습니다.
Michael Damatov

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.