Thread에서 Task

스레드를 만드는 데는 비교적 많은 리소스가 필요하고 개별 스레드의 가상 메모리 소비량도 큰 편이다(기본 1MB). 앞에서 살펴 본 것처럼 스레드 풀을 이용하면 스레드를 만들어서 비동기 작업을 처리하고 작업이 끝난 스레드를 재사용할 수 있기 때문에 매번 새로 스레드를 만드는 것보다 효과적이다.

 닷넷 프레임워크 4에서는 비동기 작업을 시작할 때마다 운영체제 스레드를 만들어서 사용하는 대신 TPL이 태스크(Task)를 만들고 작업 스케줄러에게 처리할 비동기 작업이 있음을 통보하는 방식을 도입했다. 태스크 스케줄러를 이용하는 수많은 방법이 있겠지만 기본적으로 태스크 스케줄러는 스레드 풀에 작업 스레드를 요청한다. 스레드 풀은 효율성을 높이려고 현재 진행 중인 다른 작업이 끝난 다음에 요청된 작업을 처리하는 것이 낫다고 판단할 수도 있고, 혹은 요청된 비동기 작업을 처리하기 위한 작업 스레드를 특정 프로세서에 할당할 수도 있다. 스레드 풀은 또한 새 작업을 실행하는 일에 기존의 스레드를 재활용하는 것이 나을지 혹은 새 스레드를 만들어서 사용하는 것이 효과적일지도 판단한다.

 Task 개체의 안쪽에 내장하도록 비동기 작업을 추상화함으로써 TPL은 비동기 작업을 대변하는 개체를 제공하고 필요한 작업과 상호작용이 가능한 개체 지향 API를 제공할 수 있다. 그리고 작업의 단위를 표현하는 개체를 제공하므로 TPL은 프로그래밍을 통해 작은 작업들로 구성된 큰 작업을 워크플로우로 구성할 수 있으며, 이 점을 이후에 살펴본다.

 태스크는 비동기로 수행할 작업을 캡슐화하는 개체다. 코드를 대변하는 개체라는 점에서 대리자의 개념과 비슷하게 들릴 수 있다. 대리자는 동기적이며 태스크는 비동기적이라는 점에서 차이가 난다. , 예를 들어 Action과 같은 대리자를 실행하면 현재 스레드의 제어점은 즉시 대리자 코드로 이동하고 대리자의 실행이 끝날 때까지 제어를 반환하지 않는다. 이와 대조적으로 태스크는 처리해야 할 작업의 양과 무관하게 태스크 시작과 동시에 호출측으로 제어를 반환한다. 태스크는 비동기적으로 실행되며 보통 별도의 스레드를 이용한다.(이번 장의 뒤에서 살펴 볼 것인데, 사실 스레드 한 개만 이용해서 태스크들을 비동기적으로 실행하는 것이 가능하며 또 이득이 되기도 한다.) 태스크는 본질적으로 대리자를 동기적은 형태에서 비동기 실행 패턴으로 변환한다.

 

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

 

+ Recent posts