스레드 대 스레드 풀


137

새 스레드를 사용하는 것과 스레드 풀의 스레드를 사용하는 것의 차이점은 무엇입니까? 어떤 성능 이점이 있으며, 명시 적으로 만든 스레드가 아닌 풀의 스레드를 사용해야하는 이유는 무엇입니까? 나는 여기서 .NET을 특별히 생각하고 있지만 일반적인 예는 좋습니다.

답변:


110

스레드 풀은 다음과 같이 빈번하고 비교적 짧은 작업에 이점을 제공합니다.

  • 새 스레드를 작성하는 대신 이미 작성된 스레드 재사용 (고가의 프로세스)
  • 새로운 작업 항목에 대한 요청이 급증 할 때 스레드 생성 속도 조절 (이것은 .NET 3.5에만 해당됨)

    • 100 개의 스레드 풀 작업을 대기열에 넣는 경우 이러한 요청을 처리하기 위해 이미 생성 된 수의 스레드 만 사용합니다 (예 : 10). 스레드 풀은 자주 확인하고 (3.5 SP1에서 500ms마다 믿습니다) 대기중인 작업이있는 경우 하나의 새 스레드를 만듭니다. 작업이 빠르면 새 스레드 수가 적고 짧은 작업에 10 개 정도의 스레드를 다시 사용하면 100 개의 스레드를 미리 만드는 것보다 빠릅니다.

    • 워크로드에 지속적으로 많은 수의 스레드 풀 요청이 들어오는 경우, 스레드 풀은 위 프로세스에 의해 풀에 더 많은 스레드를 작성하여 요청을 처리하는 데 사용할 수있는 스레드 수가 더 많아 지므로 워크로드에 맞게 조정됩니다.

    • 스레드 풀이 후드 아래에서 작동하는 방법에 대한 자세한 내용은 여기 를 확인하십시오.

작업이 비교적 오래 실행되는 경우 (아마도 1-2 초 정도이지만 특정 상황에 따라 다름) 새 스레드를 직접 만드는 것이 더 적합합니다.

@Krzysztof-스레드 풀 스레드는 기본 스레드가 끝나면 중지되는 백그라운드 스레드입니다. 수동으로 생성 된 스레드는 기본적으로 포 그라운드이지만 (메인 스레드가 종료 된 후에도 계속 실행 됨) 시작을 호출하기 전에 백그라운드로 설정할 수 있습니다.


5
내가 궁금한 것은 MSDN의 다음 문장 ( msdn.microsoft.com/en-us/library/1c9txz50.aspx )입니다. "백그라운드 스레드는 실행중인 포 그라운드 스레드 수가 프로세서 수보다 적은 경우에만 실행됩니다. ". 그것은 코어들 사이에서 작업을 나눌 때 포 그라운드 스레드가 우선권을 갖음을 의미합니까?
cdiggins

1
➤ 스레드 풀에서 스레드를 중단하거나 중단 할 수 없습니다. ➤ 스레드 풀에서 스레드를 결합 할 수 없습니다. 이를 위해서는 다른 메커니즘을 사용해야합니다
Zinov

14

.NET 관리 스레드 풀 :-

  • 현재 워크로드 및 사용 가능한 하드웨어를 기반으로 자체 크기 조정
  • 작업자 스레드 완료 포트 스레드 (IO를 서비스하는 데 특별히 사용됨)를 포함합니다.
  • 상대적으로 수명이 짧은 수많은 작업에 최적화

장기 실행 작업에 더 적합한 다른 스레드 풀 구현이 있습니다.

특히 스레드 풀을 사용하여 앱이 너무 많은 스레드 를 만들지 못하게합니다 . 스레드 풀의 가장 중요한 기능은 작업 대기열입니다. 즉, 시스템이 충분히 사용 중이면 스레드 풀은 더 많은 스레드를 즉시 생성하지 않고 요청을 대기시킵니다.

따라서 작은 수의 스레드를 만들면 직접 만들 수 있습니다. 얼마나 많은 스레드가 생성되는지 (예 : 들어오는 IO에 대한 응답으로 생성 된) 선행 작업을 결정할 수없고 작업이 오래 지속되는 경우 스레드 풀을 사용하십시오. 몇 개인 지 모르지만 그 작업이 오래 실행되는 경우 플랫폼에 도움이되는 것은 없지만 적합한 스레드 풀 구현을 찾을 수 있습니다.


.NET에서 스레드 풀없이 완료 포트를 사용할 수 있습니까? 비동기 I / O 메서드가 .NET에서 유일한 방법이며 스레드 풀을 사용한다고 가정했습니다.
Karg

10

또한

new Thread().Start()

프로그램을 닫아도 죽지 않는 포 그라운드 스레드를 생성합니다. ThreadPool 스레드는 앱을 닫을 때 죽는 백그라운드 스레드입니다.


11
언제든지 스레드를 배경으로 설정할 수 있습니다. 기본적으로 전경입니다.
Kris Erickson

3
니모 : var t = new Thread (...); t.BackgroundThread = 참; t. 시작 ();
Ricardo Amores

18
"프로그램"이라는 용어에 대한 설명. 데스크톱 응용 프로그램은 프로세스에서 실행되며 UI를 관리하는 하나 이상의 포 그라운드 스레드가 있습니다. 포 그라운드 스레드가있는 한 해당 프로세스는 계속 실행됩니다. 데스크톱 응용 프로그램을 닫을 때 포 그라운드 UI 스레드는 중지되지만 다른 포 그라운드 스레드가있는 경우 프로세스를 반드시 중지 할 필요는 없습니다 .
G-Wiz

8

나는 이들의 상대적인 리소스 사용에 대해 궁금했고 Windows 8에서 .net 4.0 릴리스 빌드를 사용하여 2012 듀얼 코어 Intel i5 랩톱에서 벤치 마크를 실행했습니다. 스레드 풀은 평균 0.035ms가 소요되어 스레드는 평균 5.06을 차지했습니다. ms. 다시 말해 풀의 스레드는 많은 짧은 스레드 스레드에 대해 약 300 배 더 빠르게 시작되었습니다. 적어도 테스트 된 범위 (100-2000) 스레드에서 스레드 당 총 시간은 꽤 일정 해 보입니다.

이것은 벤치마킹 된 코드입니다.

    for (int i = 0; i < ThreadCount; i++) {
        Task.Run(() => { });
    }

    for (int i = 0; i < ThreadCount; i++) {
        var t = new Thread(() => { });
        t.Start();
    }

여기에 이미지 설명을 입력하십시오


5
ThreadPool이 새로운 스레드를 생성하는 대신 생성 된 스레드를 재사용하기 때문에 많은 비용이 소요됩니다.
fabriciorissetto


1

스레드 로컬 저장소는 스레드 풀에 적합하지 않습니다. 스레드에 "정체성"을 제공합니다. 모든 스레드가 더 이상 같은 것은 아닙니다. 이제 스레드 풀은 동일한 오버 헤드가 필요하고 생성 오버 헤드없이 작업을 수행 할 준비가 된 경우 특히 유용합니다.


1

많은 스레드가 필요한 경우 ThreadPool을 사용하고 싶을 것입니다. 스레드를 재사용하여 스레드 작성의 오버 헤드를 줄입니다.

무언가를하기 위해 하나의 스레드 만 필요한 경우 스레드가 가장 쉽습니다.


1

theadpool 스레드의 주요 요구 사항은 거의 즉시 완료 될 것으로 예상되는 짧은 작업을 처리하는 것입니다. 하드웨어 인터럽트 처리기는 종종 커널이 아닌 코드에는 적합하지 않은 스태킹 컨텍스트에서 실행되지만 하드웨어 인터럽트 처리기는 사용자 모드 I / O 완료 콜백이 가능한 빨리 실행되어야한다는 것을 알 수 있습니다. 그러한 것을 실행하기 위해 새로운 스레드를 만드는 것은 엄청난 과잉 일 것입니다. I / O 완료 콜백 또는 기타 유사한 것들을 실행하기 위해 디스패치 할 수있는 미리 작성된 스레드가 몇 개있는 것이 훨씬 더 효율적입니다.

이러한 스레드의 주요 측면은 I / O 완료 방법이 항상 본질적으로 즉시 완료되고 차단되지 않는 경우, 현재 이러한 방법을 실행하는 이러한 스레드 수는 다른 스레드의 유일한 방법 인 프로세서 수와 최소한 동일하다는 것입니다 다른 방법 중 하나가 차단되거나 실행 시간이 정상적인 스레딩 시간 조각을 초과하는 경우 전술 한 방법 중 하나가 완료되기 전에 실행될 수 있습니다. 스레드 풀이 의도 한대로 사용되는 경우에는이 중 어느 것도 자주 발생하지 않아야합니다.

메소드가 실행을 시작할 때 100ms 이내에 종료 될 것으로 예상되지 않으면 메소드는 기본 스레드 풀 이외의 다른 수단을 통해 실행되어야합니다. 수행해야 할 작업이 많지만 CPU를 많이 사용하지만 차단하지 않는 경우 "주"스레드 풀과 분리 된 응용 프로그램 스레드 풀 (CPU 코어 당 하나)을 사용하여 작업을 디스패치하는 것이 도움이 될 수 있습니다. 비 블로킹 CPU를 많이 사용하는 작업을 실행할 때는 코어보다 많은 스레드가 비생산적입니다. 그러나 메소드가 실행하는 데 1 초 이상 걸리고 대부분의 시간이 차단되는 경우 메소드는 전용 스레드에서 실행되어야하고 거의 확실하게 메인 스레드 풀 스레드에서 실행되지 않아야합니다. I / O 콜백과 같이 장기 실행 작업을 트리거해야하는 경우,


0

일반적으로 (.NET을 사용한 적이 없다), 리소스 관리 목적으로 스레드 풀이 사용됩니다. 제약 조건을 소프트웨어에 구성 할 수 있습니다. 새 스레드를 만드는 데 많은 비용이 들기 때문에 성능상의 이유로 수행 될 수도 있습니다.

시스템 특정 이유가있을 수도 있습니다. Java에서 (이것이 .NET에 적용되는지 알지 못합니다), 스레드 관리자는 각 스레드가 풀에서 풀링 될 때 스레드 특정 변수를 적용하고 반환 될 때 설정 해제 할 수 있습니다 (일반적인 방법은 정체성).

제약 조건 예 : 10 개의 DB 연결 만 있으므로 데이터베이스에 액세스하기 위해 10 개의 작업자 스레드 만 허용합니다.

이것은 당신이 당신의 자신의 스레드를 생성해서는 안된다는 것을 의미하지는 않지만 풀을 사용하는 것이 합리적 인 조건이 있습니다.


0

작성 될 스레드 수를 모르거나 제어 할 수없는 경우 풀을 사용하는 것이 좋습니다.

목록 컨트롤의 위치 변경 이벤트 (freez를 피하십시오)에서 데이터베이스의 일부 필드를 업데이트하기 위해 스레드를 사용하는 양식에 문제가 있습니다. 사용자가 목록 위치를 너무 빨리 변경했기 때문에 데이터베이스에서 Access에 너무 많은 연결이 발생하는 데 5 분이 걸렸습니다.

기본 문제를 해결하는 다른 방법이 있다는 것을 알고 있습니다 (액세스 사용하지 않음 포함). 풀링은 좋은 시작입니다.


0

:

  1. 스레드 생성은 스레드 풀을 사용하는 것보다 훨씬 느립니다.
  2. 스레드의 우선 순위를 변경할 수 있습니다.
  3. 자원과 관련된 프로세스의 최대 스레드 수입니다.
  4. 스레드는 OS 수준에 있으며 OS에 의해 제어됩니다.
  5. 작업이 상대적으로 오래 실행되는 경우 스레드를 사용하는 것이 더 나은 옵션입니다.

실풀 :

  1. 스레드 풀에서 스레드를 실행하면 스레드를 직접 만드는 것보다 훨씬 빠릅니다.
  2. 스레드 풀을 기반으로 스레드 실행의 우선 순위를 변경할 수 없습니다.
  3. 프로세스 당 하나의 스레드 풀만 있습니다.
  4. 스레드 풀은 CLR에서 관리합니다.
  5. 스레드 풀은 수명이 짧은 작업에 유용합니다.
  6. 스레드 풀의 스레드 수는 응용 프로그램로드와 관련이 있습니다.
  7. TPL 작업은 스레드 풀을 기반으로 실행됩니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.