IOCP에 concurrency 값을 지정하고 워커 스레드를 따로 만들었습니다. 이 값은 생성한 스레드 수와 무엇이 다른가요?
잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?
답변과 점검 포인트 펼치기답변 접기
구두 답변
정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.
IOCP의 concurrency 값은 워커 스레드를 몇 개 생성할지 정하는 값이 아니라, 완료 포트에 연결된 실행 스레드 중 동시에 실행 상태로 허용할 규모를 제어하는 값입니다. 워커 스레드는 애플리케이션이 직접 만들어 GetQueuedCompletionStatus를 기다리게 합니다. 따라서 워커 수와 concurrency를 같게 두는 것은 하나의 선택일 뿐이며, 값이 요청 순서나 연결별 상호 배제를 보장하지도 않습니다.
생성 수와 실행 수
서버가 워커 16개를 생성하고 포트 concurrency를 8로 설정해도 운영체제가 스레드 8개를 자동 생성하거나 나머지를 삭제하는 것은 아닙니다. 대기 중인 워커와 완료 처리를 실행 중인 워커의 관계를 포트가 조절합니다. 완료가 큐에 있고 실행 가능한 워커가 부족하면 깨울 수 있지만, 이미 concurrency만큼 실행 중이면 추가 워커가 즉시 처리하지 않을 수 있습니다. 이를 실행 동시성 힌트(concurrency hint)와 스레드 생성 정책(thread creation policy)의 분리라고 부르겠습니다.
CPU 중심의 짧은 완료 처리라면 논리 CPU 수 근처의 워커와 적절한 concurrency가 컨텍스트 전환과 캐시 경합을 줄일 수 있습니다. 반대로 워커가 동기 DB 호출이나 외부 API에 오래 막히면 다른 완료가 밀릴 수 있습니다. 이때 concurrency를 무작정 높이면 더 많은 블로킹과 하위 부하가 생기므로, 긴 작업을 별도 제한 풀로 보내거나 비동기 API로 바꾸겠습니다. IOCP 워커가 블로킹을 포함해도 괜찮다는 의미가 아니라, 블로킹 구간의 소유권과 상한을 별도 설계해야 한다는 뜻입니다.
측정과 상태 보호
완료 큐 대기 시간, 워커가 실제 처리 중인 시간, CPU 사용률, 컨텍스트 스위치, 외부 호출 대기, 포트에 남은 패킷을 분리해 측정합니다. concurrency를 높여 처리량이 올라도 p99와 하위 오류율이 나빠지면 채택하지 않습니다. 연결별 메시지 순서나 동시에 같은 상태를 수정하지 않는 규칙은 completion key나 concurrency가 아니라 연결 상태 머신·송신 큐·락으로 구현해야 합니다.
워커 수를 너무 적게 두면 한 워커 장애나 긴 작업이 전체 처리를 막고, 너무 많이 두면 실행 경쟁과 메모리 비용이 커집니다. 종료 시에는 concurrency와 무관하게 새 제출을 차단하고 남은 I/O 완료를 drain한 뒤 워커를 끝냅니다. 테스트는 CPU 작업, 블로킹 작업, 혼합 부하, 완료 폭주, 워커 수와 concurrency를 독립적으로 바꾼 경우를 비교하겠습니다. 값 자체보다 포트가 허용하는 실행과 애플리케이션 작업의 자원 경계를 함께 설명해야 합니다.
IOCP의 concurrency는 준비된 완료가 몇 개냐가 아니라 포트에 연결된 실행 스레드의 동시 실행을 제한하는 스케줄링 입력입니다. 워커가 GetQueuedCompletionStatus에서 대기하는 동안에는 실행 중인 것으로 세지 않는 운영체제 동작을 전제로 하되, 실제 버전과 블로킹 경로는 실험으로 확인하겠습니다. 포트 워커에서 동기 호출을 할 때는 해당 호출의 상한과 취소를 별도로 마련해야 하며, concurrency를 올려 숨기는 방식은 하위 장애를 더 많은 스레드에 전파할 수 있습니다. 측정값은 완료 큐 길이만이 아니라 워커가 어떤 상태로 시간을 보냈는지여야 합니다.
concurrency를 낮추는 것이 동시 요청의 논리 순서를 만들지는 않습니다. 같은 연결에서 수신 완료와 송신 완료가 서로 다른 워커에 도착할 수 있으므로, 상태 변경은 연결별 큐나 별도 동기화로 보호해야 합니다. 또한 포트 워커가 잠깐 긴 작업을 수행하는지와 외부 서비스가 계속 막히는지는 프로파일러와 작업별 시간 기록으로 구분하겠습니다.
득점 포인트
이해가 드러나는 지점을 확인해 보세요.
- concurrency 설정과 애플리케이션 워커 생성 수를 서로 다른 대상으로 설명한다.
- CPU 작업·블로킹 작업·하위 서비스 포화를 실행 동시성 판단에 연결한다.
- concurrency가 순서 보장이나 연결별 상호 배제를 제공하지 않는다고 짚는다.
- 큐 대기·p99·컨텍스트 스위치·외부 대기를 함께 측정한다.
감점 포인트
놓치기 쉬운 조건과 오해를 짚어 보세요.
- concurrency 값만큼 워커 스레드가 자동 생성된다고 말한다.
- concurrency 1이면 모든 연결의 요청이 원자적으로 순서 처리된다고 단정한다.
- 워커와 concurrency를 늘리면 항상 처리량과 지연이 좋아진다고 본다.
더 파고들 거리
하나 더 질문하며 이해의 범위를 넓혀 보세요.
- IOCP의 대기 worker 깨움 방식은 cache locality와 공정성에 어떤 영향을 주며 어떤 수치를 관찰하나요?
- 블로킹 callback을 별도 풀로 보냈더니 그 큐가 늘어납니다. 완료 수집과 실행 풀의 상한을 어떻게 연결하나요?
- GetQueuedCompletionStatusEx 배치가 처리량과 짧은 요청 지연을 어떻게 바꿀까요?
득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.
원리부터 공부하고 싶다면
답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.