문제

나는 내 직업에 대한 디자인 요구 사항이 많은 스레드 풀에 대한 디자인을 생각해내려고 노력하고 있습니다.이는 작동하는 소프트웨어에 대한 실제 문제이며 어려운 작업입니다.나는 작동하는 구현을 가지고 있지만 이것을 SO에 던져서 사람들이 어떤 흥미로운 아이디어를 생각해낼 수 있는지 확인하고 싶습니다. 그러면 내 구현과 비교하고 그것이 어떻게 쌓이는지 확인할 수 있습니다.가능한 한 요구 사항을 구체적으로 설명하려고 노력했습니다.

스레드 풀은 일련의 작업을 실행해야 합니다.작업은 단기 실행(1초 미만) 또는 장기 실행(몇 시간 또는 며칠)일 수 있습니다.각 작업에는 연관된 우선순위가 있습니다(1 = 매우 낮음부터 5 = 매우 높음).작업은 다른 작업이 실행되는 동안 언제든지 도착할 수 있으므로, 작업이 도착하면 스레드 풀은 이를 선택하고 스레드가 사용 가능해지면 예약해야 합니다.

작업 우선순위는 작업 길이와 완전히 독립적입니다.실제로 작업을 직접 실행하지 않고는 작업을 실행하는 데 걸리는 시간을 알 수 없습니다.

일부 작업은 CPU에 바인딩되어 있고 일부 작업은 IO에 크게 바인딩되어 있습니다.주어진 작업이 무엇인지 미리 말하는 것은 불가능합니다(비록 작업이 실행되는 동안 감지하는 것이 가능할 수도 있지만).

스레드 풀의 주요 목표는 처리량을 최대화하는 것입니다.스레드 풀은 컴퓨터의 리소스를 효과적으로 사용해야 합니다.이상적으로 CPU 바인딩 작업의 경우 활성 스레드 수는 CPU 수와 같습니다.IO 바인딩 작업의 경우 차단이 처리량에 과도한 영향을 미치지 않도록 CPU보다 더 많은 스레드를 할당해야 합니다.잠금 사용을 최소화하고 스레드 안전/빠른 컨테이너를 사용하는 것이 중요합니다.

일반적으로 더 높은 CPU 우선순위로 더 높은 우선순위의 작업을 실행해야 합니다(참조:SetThread우선순위).우선 순위가 낮은 작업은 우선 순위가 높은 작업이 실행되는 것을 "차단"해서는 안 됩니다. 따라서 우선 순위가 낮은 작업이 모두 실행되는 동안 우선 순위가 높은 작업이 나타나면 우선 순위가 높은 작업이 실행됩니다.

작업에는 "최대 실행 작업" 매개변수가 연결되어 있습니다.각 작업 유형은 한 번에 최대 이 개수의 작업 동시 인스턴스만 실행할 수 있습니다.예를 들어 대기열에 다음 작업이 있을 수 있습니다.

  • A - 인스턴스 1000개 - 낮은 우선순위 - 최대 작업 1
  • B - 인스턴스 1000개 - 낮은 우선순위 - 최대 작업 1
  • C - 인스턴스 1000개 - 낮은 우선순위 - 최대 작업 1

작동하는 구현에서는 동시에 최대 1개의 A, 1B 및 1C만 실행할 수 있습니다.

Windows XP, Server 2003, Vista 및 Server 2008(최신 서비스 팩)에서 실행해야 합니다.


참고로 다음 인터페이스를 사용할 수 있습니다.

namespace ThreadPool
{
    class Task
    {
    public:
        Task();     
        void run();
    };

    class ThreadPool
    {    
    public:
        ThreadPool();
        ~ThreadPool();

        void run(Task *inst);
        void stop();
    };
}
도움이 되었습니까?

해결책

그러면 우리는 이를 위한 기본 빌딩 블록으로 무엇을 선택할까요?Windows에는 유망해 보이는 두 가지 구성 요소, 즉 IOCP(I/O 완료 포트)와 APC(비동기 프로시저 호출)가 있습니다.이 두 가지 모두 명시적인 잠금을 수행하지 않고도 FIFO 대기열을 제공하고 스케줄러와 같은 위치에서 일정량의 내장 OS 지원을 제공합니다(예: IOCP는 일부 컨텍스트 전환을 피할 수 있음).

APC가 약간 더 적합할 수도 있지만 완전히 "투명"하지 않기 때문에 약간 주의해야 합니다.작업 항목이 경고 가능한 대기(::SleepEx, ::WaitForXxxObjectEx 등)를 수행하고 실수로 APC를 스레드에 디스패치한 경우 새로 디스패치된 APC가 스레드를 인계받아 새 APC가 실행될 때까지 이전에 실행 중인 APC를 일시 중단합니다. 완성된.이는 동시성 요구 사항에 좋지 않으며 스택 오버플로 가능성이 높아질 수 있습니다.

다른 팁

Windows XP, Server 2003, Vista 및 Server 2008(최신 서비스 팩)에서 실행해야 합니다.

시스템에 내장된 스레드 풀의 어떤 기능이 작업에 적합하지 않습니까?XP 및 2003을 대상으로 하고 싶다면 새로운 Vista/2008 풀을 사용할 수 없지만 QueueUserWorkItem 및 친구들은 계속 사용할 수 있습니다.

@DrPizza - 이것은 매우 좋은 질문이며 문제의 핵심을 꿰뚫는 질문입니다.QueueUserWorkItem과 Windows NT 스레드 풀이 배제된 데에는 몇 가지 이유가 있습니다(비록 몇 년 후에는 Vista 스레드 풀이 흥미로울 것 같지만).

첫째, 우리는 스레드가 시작되고 중지되는 시점을 더 효과적으로 제어하고 싶었습니다.NT 스레드 풀은 작업이 짧게 실행된다고 생각하면 새 스레드를 시작하는 것을 꺼린다고 들었습니다.WT_EXECUTELONGFUNCTION을 사용할 수 있지만 작업이 긴지 짧은지 전혀 알 수 없습니다.

둘째, 스레드 풀이 이미 오래 실행되고 우선 순위가 낮은 작업으로 채워져 있으면 우선 순위가 높은 작업이 적시에 실행될 가능성이 없습니다.NT 스레드 풀에는 작업 우선 순위에 대한 실제 개념이 없으므로 QueueUserWorkItem을 수행하고 "아 그런데 이 항목을 바로 실행하세요"라고 말할 수 없습니다.

셋째, (MSDN에 따르면) NT 스레드 풀은 STA 아파트 모델과 호환되지 않습니다.이것이 무엇을 의미하는지 잘 모르겠지만 모든 작업자 스레드는 STA에서 실행됩니다.

@DrPizza - 이것은 매우 좋은 질문이며 문제의 핵심을 꿰뚫는 질문입니다.QueueUserWorkItem과 Windows NT 스레드 풀이 배제된 데에는 몇 가지 이유가 있습니다(비록 몇 년 후에는 Vista 스레드 풀이 흥미로울 것 같지만).

예, Vista에서는 기능이 상당히 강화되어 이제는 매우 다재다능해졌습니다.

좋아, 우선 순위가 어떻게 작동하기를 원하는지 아직 약간 불분명합니다.풀이 현재 최대 동시성 1이고 우선순위가 낮은 유형 A의 작업을 실행 중이고 유형 A(및 최대 동시성 1)의 새 작업이 주어지지만 이번에는 우선순위가 높은 경우 어떻게 해야 합니까? ?

현재 실행 중인 A를 일시 중지하면 문제가 발생합니다(새 작업이 수행해야 하는 잠금을 보유하여 시스템이 교착 상태에 빠질 수 있음).두 번째 스레드를 생성할 수 없으며 단지 함께 실행되도록 허용됩니다(허용되는 동시성은 1입니다).그러나 낮은 우선순위 작업이 완료될 때까지 기다릴 수 없습니다. 런타임이 제한되지 않고 그렇게 하면 낮은 우선순위 작업이 높은 우선순위 작업을 차단할 수 있기 때문입니다.

내 추측은 당신이 추구하는 후자의 행동이라는 것입니까?

@DrPizza:

좋아, 나는 당신이 우선 순위가 어떻게 일하기를 바라는 지에 대해 여전히 불분명합니다.풀이 현재 최대 동시성 1이고 우선 순위가 낮은 타입 A 작업을 실행하고 있고, 유형 A (및 최대 동시성 1)의 새로운 작업이 주어 지지만 이번에는 우선 순위가 높은 경우 어떻게해야합니까? ?

이것은 다소 까다로운 작업이지만, 이 경우 우선 순위가 낮은 작업을 완료하도록 허용하는 것만으로도 만족할 것 같습니다.일반적으로 스레드 우선순위가 다른 동일한 유형의 작업이 많이 표시되지 않습니다.우리 모델에서는 잘 정의된 특정 지점에서 작업을 안전하게 중지했다가 나중에 다시 시작하는 것이 실제로 가능합니다(이와 다른 이유로). 이로 인해 발생할 수 있는 합병증은 아마도 위험을 감수할 가치가 없을 것입니다.

일반적으로 서로 다른 유형의 작업만 서로 다른 우선순위를 갖습니다.예를 들어:

  • 작업 - 1000개 인스턴스 - 낮은 우선순위
  • B 작업 - 인스턴스 1000개 - 우선순위 높음

A 작업이 시작되어 실행 중이고 B 작업이 도착했다고 가정하면 B 작업이 거의 즉시 실행될 수 있기를 원할 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top