3-15 스레드 풀링(Pooling)
- 스레드 풀
- 스레드 풀 구현
스레드 풀
스레드 풀의 필요성
스레드의 생성과 소멸이 빈번히 일어나면 시스템이 부담
-> 하나의 동작을 위해 하나의 스레드가 생성 후 소멸되고 다시 다른 동작을 위해 다른 스레드 생성/소멸 = 비효율적
스레드 풀
할당된 동작을 마친 스레드를 소멸시키지 않고 스레드 풀에 저장해두었다가 필요한 경우 다시 재사용
-> n개의 동작이 요구되면, 미리 스레드 풀 내부에 저장해둔 스레드를 통해 해당 동작을 처리하고 다시 스레드 풀로 반환
스레드 풀 구현
스레드 풀 구현 고려사항
1. 스레드를 어떻게 동작에 할당할 것인가?
2. 동작을 마무리한 스레드를 어떻게 스레드 풀 내부에 다시 저장할 것인가?
스레드 풀 구현
-> 스레드를 저장할 구조체 선언 : WorkerThread 구조체 : 구조체 내부에 핸들과 ID 정보 포함
-> 스레드 풀 구조체 선언 : ThreadPool
-> 스레드가 취할 가능성이 있는 동작들에 대한 정보가 포함된 배열 선언 : workList[]
-> 스레드의 정보가 포함되는 배열 선언(WorkerThread 구조체가 멤버로) : workerThreadList[]
-> 스레드의 이벤트 오브젝트가 저장되는 배열 : workerEventList[]
-> 처리되어야 하는 동작의 위치 : idxOfCurrentWork
-> 처리되어야 하는 마지막 동작의 위치 : idxOfLastAddedWork
-> 현재 풀에 저장된 스레드 개수 : threadIdx
스레드에게 동작 부여 = 스레드가 호출해서 실행할 함수를 지정해준다는 의미
-> 만약 할당된 일이 없다면 스레드는 WaitForSingleObject() 함수로 Block 상태로 대기하고 있어야 함
-> 이벤트가 발생하면 실행되어야 하고, 이를 위해서는 스레드 하나 당 이벤트 오브젝트 하나가 필요
-> 위 이벤트 오브젝트들은 workerEventLis[]에 배열로 저장되어 있음
스레드 풀 동작
1. (Pool이 구현되어있다는 가정하에) MakeThreadToPool() 함수로 스레드를 생성하여 풀에 등록
2. AddWorkToPool() 함수를 호출하여 스레드가 처리할 동작을 등록
3. 동작이 등록되었다면 풀에서 모든 이벤트 오브젝트는 Signaled 상태로 변경 = 모든 스레드가 실행 상태로 변경
4. Work를 할당 받는 하나의 스레드를 제외하고 다시 Block 상태로 전환
5. Running 상태에 들어간 하나의 스레드는 GetWorkFromPool() 함수를 통해 동작(함수 포인터)를 할당 받아 함수 실행