[멀티쓰레드 프로그래밍] 쓰레드 풀링

Jin Hur·2022년 7월 11일
0

멀티쓰레드 모델의 서버를 개발할 때 쓰레드는 몇 개를 만들고, 각 쓰레드는 무엇을 위해 일을 하게 만들면 좋을까?

방법 1. 클라이언트마다 쓰레드를 배정

가장 쉬운 개발 방법 중 하나는 클라이언트마다 쓰레드를 배정해 주는 것이다. 클라이언트가 5000개면, 쓰레드도 5000개가 되는 것이다.
이러한 방식은 개발하기는 쉽지만, 쓰레드 갯수가 많을 경우 여러 가지 문제가 발생한다.

  • 각 쓰레드는 호출 스택을 가지는데, 이것의 크기는 작게는 수십 KB에서 수 MB에 이른다. 쓰레드가 5000개고, 각 쓰레드마다 호출 스택이 1MB라고만 해도 필요한 메모리는5000MB에 이른다.

  • 문맥 교환이 너무 빈번하게 발생된다. CPU가 충분히 많을 지라도, 5000개에, 아니 그 이상의 쓰레드가 동작하기엔 문맥 교환이 필연적으로 많이 발생할 것이다.


방법 2. 쓰레드 풀링(thread pooling)

쓰레드 개수를 클라이언트 개수만큼 두는 일은 요즘에는 거의 없다. 대신 쓰레드 풀링을 한다.

쓰레드 풀링은 공중 화장실에 비유할 수 있다.
공중 화장실에는 문이 여러 개 있고, 여러 문 앞에서 일렬로 사람들이 줄을 서서 기다린다. 사용 중이 아닌 문이 하나라도 있으면 하나를 골라서 들어간다. 그리고 모든 문이 사용중이면 하나가 사용 가능해질 때까지 기다려야 한다.

각 문은 쓰레드이고, 줄 서 있는 사람들은 처리할 이벤트로 비유할 수 있다. 여러 문의 집합, 즉 화장실은 쓰레드 풀이다.
이렇게 하면 많은 수의 이벤트를 동시에 여러 쓰레드에서 처리할 수 있으면서 너무 많은 쓰레드를 두었을 때 발생하는 문제점을 방지할 수 있다. 쓰레드 개수가 많으면 그만큼 동시에 여러 일을 처리할 수 있지만, 너무 많으면 앞서 설명한 것과 같은 문제점들이 발생한다.
따라서 쓰레드 개수는 적정한 선이 필요하다.

쓰레드 풀의 적절한 숫자는?

예를 들어 CPU 코어가 8개 있는 기기가 있고 쓰레드를 8개 갖고 있다고 치자. 각 쓰레드는 자주 잠을 잔다. 이 경우 CPU는 대기를 하는 시간을 종종 가지므로 결과적으로 CPU 연산량이 떨어질 수 밖에 없다(CPU 자원을 효율적으로 사용하지 못하는 상황).

이왕 CPU가 놀 것이라면 노는 시간 동안 다른 일을 더 처리하도록 하면 좋다. 쓰레드 개수를 CPU 갯수보다 더 많이 배정하면 된다.
예를 들어 일을 처리하는 총 시간의 1/4이 CPU 연산이고, 3/4이 잠자는(또는 wait 상태) 시간이라면, CPU가 더 일을 배정받을 수 있는 시간이 3배 더 남는 셈이다. 이 경우 쓰레드 개수를 CPU 개수의 3배, 즉 32개 배정하는 것이 적절하다는 계산이 나온다.

요약하자면,

  • 어떤 서버의 주 역할이 CPU 연산만 하는 쓰레드라면(즉, 디바이스 타임이 없다면) 쓰레드 풀의 쓰레드 개수는 서버의 CPU 개수와 동일하게 잡아도 충분하다.

  • 서버에서 데이터베이스나 파일 등 다른 것에 액세스하면서 디바이스 타임이 발생할 때 쓰레드 개수는 CPU 개수보다 많아야 한다.


쓰레드 풀링, 좀 더 자세히..

reference: https://popcorntree.tistory.com/67

쓰레드의 생성과 소멸은 시스템에 많은 부담을 준다. 때문에 빈번한 쓰레드의 생성과 소멸은 피해야 한다.
따라서 쓰레드 풀을 유지하는 것은 성능 향상에 도움이 된다.

  • 쓰레드 풀의 기본 원리는 쓰레드의 재활용이다.
  • 할당된 일을 마친 쓰레드를 소멸시키지 않고, 쓰레드 풀에 저장해 뒀다가 필요할 때 다시 꺼내 쓰는 개념이다.

즉, 쓰레드의 생성과 소멸에 필요한 비용을 지불하지 않겠다는 것이다.

source: https://popcorntree.tistory.com/67

쓰레드 풀은 처리해야 할 일(work)이 등록되기 전에 생성되는데, 풀이 생성됨과 동시에 쓰레드들도 생성되어 풀에서 대기하게 된다.
쓰레드 풀에 존재하는 쓰레드 하나를 임의로 할당해서 일의 처리를 도모한다.
만약 풀에 존재하는 쓰레드 수보다 처리해야 할 일의 수가 많다면, 일이 순서대로 처리되도록 디자인할 수 있고, 빠른 일 처리를 위해 추가적인 쓰레드가 생성되도록 풀을 디자인할 수도 있다. 

0개의 댓글