스레드 폴링

프로세서에 의존하는 작업에 효과적으로 프로세서 시간을 할당하려면 스레드 풀을 활용한다.

입출력 관련 혹은 장기간 수행되는 작업의 경우, 스레드 풀의 스레드를 할당하지 말고 TPL을 이용하라

 

앞서 성능에 대한 고려사항을 살펴본 것처럼 스레드를 과도하게 사용하면 오히려 성능에 악영향을 미칠 수 있다. 스레드는 비교적 비싼 대가를 요구하는 자원이며 스레드 콘텍스트 변경은 공짜가 아닐 뿐더러 시분할 방식을 이용해서 두 개의 작업을 병렬 처리 형태로 모의하는 것은 한 개씩 실행하는 방식에 비해서 훨씬 느릴 수 있다.

 이와 같은 문제점에 효과적으로 대응하려고 BCL은 스레드 풀을 제공한다. 스레드를 직접 할당하는 대신에 처리하고자 하는 작업이 무엇인지 스레드 풀에 요청할 수 있다. 작업이 끝나면 스레드를 종료하고 제거하는 대신 스레드 풀에 반납하는 방식을 이용하기 때문에 작업이 요청되었을 때 새로운 스레드를 할당하는 데 들어가는 비용을 절약할 수 있다.

훨씬 더 많은 작업들을 비동기 처리하는데 이와 같은 풀링(pooling) 기법을 적용하면 더욱 큰 효과를 얻을 수 있을 것이다. 이런 효율성을 얻을 수 있는 이유는 매번 비동기 호출이 있을 때마다 스레드를 다시 만들지 않고 계속해서 재사용하기 때문이다. 스레드 풀 방식을 사용할 때도 여전히 성능과 동기화 문제를 피할 수 없으므로 세심하게 다뤄야한다.

프로세서를 효과적으로 사용하려고 스레드 풀은 스레드 풀을 이용해서 처리하는 모든 작업이 적절한 시간 내에 끝나고 결과적으로 반환된 스레드를 다른 작업에 재사용할 수 있다는 가정 하에 동작한다. , 스레드 풀은 모든 작업이 비교적 짧은 시간에 끝날 것이라고 가정한다.(밀리초 혹은 초 단위로 끝나는 작업 정도를 의미하며, 몇 시간이나 혹은 며칠씩 처리해야하는 작업은 고려치 않는다.) 이와 같은 가정을 기반으로 성능과 관련한 초급 주제를 살펴 본 것처럼 스레드 풀은 개별 프로세서가 작업에 최대한의 능력을 발휘하고 다양한 작업을 비효율적인 시분할 없이 처리할 수 있다. 스레드 풀은 스레드 생성을 조절해서 프로세서 한 개에 너무 많은 스레드가 할당되지 않도록 함으로써 과도한 시분할이 발생하지 않게 한다. 하지만 이렇게 함으로써 스레드 풀의 스레드가 모두 사용 중인 경우에 대기 중인 작업에 지연이 발생할 수 있다. 장시간 수행하거나 혹은 I/O와 관련된 작업에 스레드 풀의 모든 스레드가 이용되고 있다면 대기 중인 작업에 지연이 있을 수 있다.

 개발자가 직접 조작할 수 있는 개체인 Thread Task와 달리 스레드 풀은 주어진 작업을 처리하는 스레드에 대한 참조를 제공하지 않는다. 그러므로 호출하는 스레드는 앞에서 살펴본 스레드 관리 함수들을 이용해서 동기화나 기타 각종 제어를 작업 스레드에 요구할 수 없다.

 스레드 풀은 오랜 시간이 필요하거나 다른 스레드와 동기화가 필요한 작업에는 적합하지 않다. 진정 우리에게 필요한 것은 스레드와 스레드 풀을 구현으로써 이용할 수 있는 상위 수준의 추상화 계층을 구현하는 것인데, 테스크 병렬 라이브러리(TPL)가 바로 이러한 것을 가능하게 해준다.

 

 

 - Essential C# 5.0 (C#의 기초와 고급을 아우르는 핵심 바이블) - 18장 다중 스레딩

 

+ Recent posts