다음을 통해 공유


관리되는 스레드 풀

이 클래스는 System.Threading.ThreadPool 시스템에서 관리하는 작업자 스레드 풀을 애플리케이션에 제공하여 스레드 관리가 아닌 애플리케이션 작업에 집중할 수 있도록 합니다. 백그라운드 처리가 필요한 짧은 작업이 있는 경우 관리되는 스레드 풀은 여러 스레드를 쉽게 활용할 수 있는 방법입니다. 프레임워크 4 이상에서는 스레드 풀 스레드에서 비동기 작업을 수행하는 TaskTask<TResult> 객체를 생성할 수 있으므로 스레드 풀 사용이 훨씬 더 쉬워졌습니다.

.NET은 TPL(작업 병렬 라이브러리) 작업, 비동기 I/O 완료, 타이머 콜백, 등록된 대기 작업, 대리자를 사용하는 비동기 메서드 호출 및 System.Net 소켓 연결을 비롯한 여러 용도로 스레드 풀 스레드를 사용합니다.

스레드 풀 특성

스레드 풀 스레드는 백그라운드 스레드입니다. 각 스레드는 기본 스택 크기를 사용하고, 기본 우선 순위에서 실행되며, 다중 스레드 아파트에 있습니다. 스레드 풀의 스레드가 작업을 완료하면 대기 중인 스레드의 큐로 반환됩니다. 이 순간부터 다시 사용할 수 있습니다. 이 재사용을 통해 애플리케이션은 각 작업에 대해 새 스레드를 만드는 비용을 방지할 수 있습니다.

프로세스당 하나의 스레드 풀만 있습니다.

스레드 풀 스레드의 예외

스레드 풀 스레드에서 처리되지 않은 예외는 프로세스를 종료합니다. 이 규칙에는 다음 세 가지 예외가 있습니다.

자세한 내용은 관리되는 스레드의 예외를 참조하세요.

스레드 풀 내 스레드의 최대 수

스레드 풀에 큐에 대기할 수 있는 작업의 수는 사용 가능한 메모리에 의해서만 제한됩니다. 그러나 스레드 풀은 프로세스에서 동시에 활성화될 수 있는 스레드 수를 제한합니다. 모든 스레드 풀 스레드가 사용 중인 경우 스레드를 실행할 수 있게 될 때까지 추가 작업 항목이 큐에 대기됩니다. 프로세스에 대한 스레드 풀의 기본 크기는 가상 주소 공간의 크기와 같은 몇 가지 요인에 따라 달라집니다. 프로세스는 메서드를 ThreadPool.GetMaxThreads 호출하여 스레드 수를 확인할 수 있습니다.

ThreadPool.GetMaxThreadsThreadPool.SetMaxThreads 메서드를 사용하여 최대 스레드 수를 제어할 수 있습니다.

비고

공용 언어 런타임을 호스트하는 코드는 메서드를 사용하여 ICorThreadpool::CorSetMaxThreads 크기를 설정할 수 있습니다.

스레드 풀 최소값

스레드 풀은 각 범주에 대해 지정된 최소값에 도달할 때까지 요청 시 새 작업자 스레드 또는 I/O 완료 스레드를 제공합니다. 이 메서드를 ThreadPool.GetMinThreads 사용하여 이러한 최소값을 가져올 수 있습니다.

비고

수요가 낮으면 실제 스레드 풀의 스레드 수가 최소값 이하로 떨어질 수 있습니다.

최소값에 도달하면 스레드 풀이 추가 스레드를 만들거나 일부 작업이 완료될 때까지 기다릴 수 있습니다. 스레드 풀은 처리량을 최적화하기 위해 작업자 스레드를 만들고 삭제하며, 이는 시간 단위당 완료되는 작업 수로 정의됩니다. 스레드가 너무 적으면 사용 가능한 리소스를 최적으로 사용하지 못할 수 있지만 스레드가 너무 많으면 리소스 경합이 증가할 수 있습니다.

주의

이 메서드를 ThreadPool.SetMinThreads 사용하여 최소 유휴 스레드 수를 늘릴 수 있습니다. 그러나 이러한 값을 불필요하게 늘리면 성능 문제가 발생할 수 있습니다. 너무 많은 작업이 동시에 시작되면 모든 작업이 느린 것처럼 보일 수 있습니다. 대부분의 경우 스레드 풀은 스레드를 할당하기 위한 자체 알고리즘을 사용하여 더 나은 성능을 발휘합니다.

스레드 풀 사용

스레드 풀을 사용하는 가장 쉬운 방법은 TPL(작업 병렬 라이브러리)을 사용하는 것입니다. 기본적으로 TaskTask<TResult> 같은 TPL 형식은 스레드 풀 스레드를 사용하여 작업을 실행합니다.

관리 코드에서 ThreadPool.QueueUserWorkItem를 호출하거나, 관리되지 않는 코드에서 ICorThreadpool::CorQueueUserWorkItem를 호출하고, 작업을 수행하는 메서드를 나타내는 대리자 System.Threading.WaitCallback를 전달하여 스레드 풀을 사용할 수도 있습니다.

스레드 풀을 사용하는 또 다른 방법은 ThreadPool.RegisterWaitForSingleObject 메서드를 사용하여 대기 작업과 관련된 작업 항목을 큐에 System.Threading.WaitHandle 대기시키는 것입니다. 신호를 받거나 시간이 초과될 때 대리자가 나타내는 메서드를 호출합니다. 스레드 풀 스레드는 콜백 메서드를 호출하는 데 사용됩니다.

예제를 보려면 참조된 API 페이지를 확인합니다.

보안 검사 건너뛰기

스레드 풀은 또한 ThreadPool.UnsafeQueueUserWorkItemThreadPool.UnsafeRegisterWaitForSingleObject 메서드를 제공합니다. 호출자의 스택이 큐에 대기 중인 작업을 실행하는 동안 수행된 보안 검사와 무관하다고 확신하는 경우에만 이러한 메서드를 사용합니다. ThreadPool.QueueUserWorkItemThreadPool.RegisterWaitForSingleObject 모두 호출자의 스택을 캡처하여, 스레드가 작업을 실행하기 시작할 때 그 스택을 스레드 풀 스레드의 스택에 병합합니다. 보안 검사가 필요한 경우 전체 스택을 확인해야 합니다. 검사는 안전을 제공하지만 성능 비용도 있습니다.

스레드 풀 스레드를 사용하지 말아야 할 때

스레드 풀 스레드를 사용하는 대신 사용자 고유의 스레드를 만들고 관리하는 것이 적절한 몇 가지 시나리오가 있습니다.

  • 포그라운드 스레드가 필요합니다.
  • 스레드에 특정 우선 순위가 있어야 합니다.
  • 스레드가 오랜 시간 동안 차단되도록 하는 작업이 있습니다. 스레드 풀에는 최대 스레드 수가 있으므로 많은 수의 차단된 스레드 풀 스레드가 작업을 시작하지 못할 수 있습니다.
  • 스레드를 단일 스레드 아파트 환경에 배치해야 합니다. 모든 ThreadPool 스레드는 다중 스레드 아파트에 있습니다.
  • 스레드와 연결된 안정적인 ID가 있거나 스레드를 작업에 헌정해야 합니다.

참고하십시오