지난 글에서 스레드를 생성하고, 실행해보며 간단한 스레드 사용 법을 배웠다.
하지만 스레드 사용하는 것은 회사에서 정직원을 채용하는 것 처럼 부담이 클 수 있기에 잠시 활용이 필요한 용도에서는 단기 알바를 구해 사용하는 방식을 고려해볼 수도 있다.
ThreadPool 역시 무작정 Thread의 개수를 늘리게 될 경우에 Core의 개수에 비해 너무 많은 Thread가 생기면서 비효율적인 상황이 생기게 되는데,
이런 상황에서 효율적인 상황을 위해 C#은 ThreadPool이라는 기능을 제공하여 마치 인력 사무소에서 잠시 직원을 대여하여 사용 후 반납하는 시스템으로 활용할 수 있다.
유니티 예시
유니티에서 오브젝트를 생성, 파괴하며 메모리에 부담을 주는 것이아닌 사용 시 활성 -> 사용 후 비활성 하며 메모리 및 GC 관리를 하는 ObjectPool과 유사하다.
ThreadPool의 경우는 Static 함수로 이루어져 있어 바로 사용할 수 있는 몇가지 기능들이 있다. 그 중 바로 스레드를 사용해볼 수 있는 기능을 활용해보고자 한다.
Thread.QueueUserWorkItem()
어떤한 Thread의 일처리를 간단하게 요청하는 경우 사용
Thread를 생성하던 것과 유사하지만, 매개변수로 Object 타입을 넣어주어야 사용이 가능하다. 당장은 어떤 처리를 해주지 않아도 되니 이대로 사용해보면 잘 동작하는 것을 확인할 수 있다.
또한 기존 스레드가 종료 되면 ThreadPool의 작업 또한 종료되는 것을 보아 BackGround에서 동작하는 것도 알 수 있다.
ThreadPool에게는 가급적 짧은 일감을 맡겨야한다.
ThreadPool의 Thread 개수는 한계가 정해져있기에 모든 Thread들이 일 처리 중이라면 끝난 후 다음 명령이 실행 되기에 속도가 느려질 수 있다.
그러니 위 예시 처림 While을 통해 계속 반복을 시켜 놓는 등의 작업은 지양해야한다.
실례로 ThreadPool.SetMix & Max로 스레드 풀의 최소 최대 개수를 설정 후 최대 스레드 수 만큼을 무한 루프로 지속 할당 해주니 MainThread의 일처리가 진행되지 않는 모습을 볼 수 있었다.
앞서 공부했던 ThreadPool에게 오랜 작업을 맡길 경우 문제가 생길 수 있었는데, 이 부분을 타개할 다른 방안을 C#에서 제공하고 있다.
Task란
Thread를 생성하지 않고 가볍게 일감을 처리하도록 구현하도록 도와주는 기능
Task에서 요청하는 일감 역시 ThreadPool을 통해 동작하긴 하나 여기서 TaskCreationOptions.LongRunning 옵션을 활용 해주면 따로 스레드를 관리 하게 된다.
TaskCreationOptions.LongRunning 을 활용하지 않을 경우 Task가 요청한 일감들을 ThreadPool에서 제한해놓은 Thread 개수 만큼을 다 차지해버렸기에 다음 ThreadPool이 사용되지 못하게 된다.
하지만 TaskCreationOptions.LongRunning 을 사용해줄 경우 따로 Thread 관리를 하기에 QueueUserWorkItem으로 요청한 작업이 실행 되는 것을 확인할 수 있었다.
C#에서는 직접 스레드를 생성하고 관리 하는 것 보다는 이런 식으로 ThreadPool을 활용하는 경우가 많다 하니 사용법을 잘 익혀서 추후 좋은 구조를 가진 서버를 만들어보고자한다.