1.12 스레드 풀링
멀티스레드 모델의 게임 서버를 개발할 때 스레드는 몇 개 만들고, 각 스레드는 무엇을 위해 일을 하게 만들면 좋을까요?
우리가 생각해 볼 수 있는 쉬운 개발 방법 중 하나는 클라이언트마다 스레드를 배정해 주는 것입니다. 클라이언트가 5000개면 스레드도 5000개가 되겠지요. 이러한 방식은 개발하기는 쉽지만, 스레드 개수가 많을 경우 여러 가지 문제가 발생한다는 단점이 있습니다.
각 스레드는 호출 스택을 가지는데, 이것의 크기는 작게는 수십 킬로바이트(KB)에서 수 메가바이트(Mb)에 이릅니다. 스레드가 5000개고 스레드마다 호출 스택을 1메가바이트 차지할 경우 필요한 메모리는 5000메가바이트에 이릅니다.
또 다른 문제는 심각하게 발생하는 컨텍스트 스위치 현상입니다. 물론 스레드가 거의 하는 일이 없으면 스레드 개수가 많아도 별로 문제될 것이 없습니다만, 게임 서비스 특성상 클라이언트는 서버와 통신하는 횟수가 잦습니다. 클라이언트 5000개가 초당 100회씩 처리해야 하는 이벤트가 발생한다면, 서버에서는 1초에 50만 번 스레드가 깨어났다 잤다를 반복할 것입니다. 그러면 스레드 둘 이상이 컨텍스트 스위치를 하는 횟수는 최대 50만 번에 이릅니다. 컨텍스트 스위치는 운영체제에서 하는 일이 많은 무거운 작업이므로 서버에 불필요한 CPU 연산량이 발생합니다.
따라서 스레드 개수를 클라이언트 개수만큼 두는 일은 요즘에는 거의 없다고 볼 수 있습니다. 그 대신 스레드 풀링(thread pooling)을 합니다.