ONE QUESTION AT A TIME.

천천히 생각하고, 분명하게.

TODAY’S QUESTION728 / 1500
네트워크난이도 중하5분 답변 목표 · 보강본

IOCP 서버에 수신·송신 작업이 남아 있는 채 종료 신호가 왔습니다. 워커와 완료 포트는 어떤 순서로 종료하나요?

잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?

답변과 점검 포인트 펼치기답변 접기
01

구두 답변

정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.

IOCP 포트부터 닫으면 미완료 I/O의 완료를 회수하고 OVERLAPPED·버퍼를 정리할 통로를 잃을 수 있습니다. 기본 순서는 새 연결과 새 I/O 제출을 막고, 이미 제출한 수신·송신·AcceptEx를 취소하거나 완료까지 기다리며, 완료 포트에서 결과를 모두 drain한 뒤 워커를 종료하고 마지막에 포트와 공유 자원을 해제하는 것입니다. 종료 패킷은 워커를 깨우는 수단이지 미완료 작업이 사라졌다는 증명이 아닙니다.

의존성 순서로 닫는다

완료 포트는 커널과 워커 사이의 결과 통로이고, 워커는 그 통로에서 작업 컨텍스트와 버퍼를 해제합니다. 먼저 listen 소켓의 새 accept 제출과 연결별 재제출을 막고, 종료 상태를 원자적으로 기록합니다. 기존 연결에는 논리적으로 새 메시지 수락을 중단하고 미완료 작업 수를 확인한 뒤 CancelIoEx를 요청합니다. 취소 요청이 반환돼도 완료 drain 전에는 OVERLAPPED를 재사용하지 않습니다. 이를 graceful shutdown의 의존성 순서라고 부르겠습니다.

각 완료는 정상 바이트 수, peer close, 취소 오류, 기타 실패 중 하나로 처리하고, 이미 논리적으로 닫힌 연결이라도 커널 작업의 참조와 카운터는 정리합니다. 완료 처리 도중 다음 WSARecv를 제출하는 코드가 있다면 전역 종료 플래그와 연결 종료 상태를 함께 검사해 재제출을 막습니다. 그렇지 않으면 작업 수가 0으로 내려갔다가 다시 늘어 drain이 끝나지 않거나, 포트 종료 뒤 새 작업이 매달립니다.

워커 종료 신호와 drain

PostQueuedCompletionStatus로 워커 수만큼 종료 패킷을 넣을 수 있지만, 워커가 종료 패킷을 받자마자 반환하면 큐에 있는 I/O 완료와 컨텍스트가 남을 수 있습니다. 종료 패킷은 ‘더 이상 새 작업을 만들지 말라’는 제어 신호와 연결하고, 실제 종료 조건을 제출 차단·전역 미완료 작업 수 0·필요한 완료 큐 소비로 정합니다. GQCS timeout도 작업이 모두 끝났다는 뜻이 아니므로 같은 조건으로 판단하지 않습니다.

운영 deadline을 둘 수는 있지만, deadline이 지났다고 버퍼를 강제 free하는 것은 안전한 취소가 아닙니다. 강제 종료를 선택하면 미완료 작업 수명 보장의 범위를 명시하고 프로세스 종료 같은 격리 수단으로 한정하겠습니다. 종료 로그도 다른 종료 중 워커나 닫힌 DB 풀에 의존하지 않게 별도 경로를 둡니다. 테스트는 유휴 워커, 수신 대기, 송신 진행, AcceptEx 대기, 취소와 정상 완료 경합, 완료 중 재제출을 재현해 워커가 끝난 뒤 접근 가능한 컨텍스트가 없는지 확인합니다.

종료 시점의 핵심 불변식은 새 I/O 제출이 0으로 내려간 뒤 미완료 I/O도 0이 되고, 그 이후에는 어떤 완료도 해제된 컨텍스트를 참조하지 않는다는 것입니다. 연결별 취소 완료를 전역 이벤트 하나로 합칠 때 작업 카운터를 먼저 줄이면 일시적인 0을 잘못 관찰할 수 있으므로, 상태 전이와 카운터 갱신 순서를 고정합니다. 워커 종료 패킷은 모든 I/O가 drain된 뒤 소비하게 하거나, 패킷을 받아도 drain 조건을 다시 확인하도록 합니다. 이렇게 해야 유휴 워커와 바쁜 워커가 서로 다른 종료 경로를 타지 않습니다.

전역 종료 플래그만으로는 이미 큐에 들어간 완료를 판정할 수 없으므로 제출 수·완료 수·논리 폐기 수의 관계를 불변식으로 기록하겠습니다. 모든 워커가 종료한 뒤에도 연결 컨텍스트가 남아 있다면 참조 누수이고, 그 컨텍스트를 사용할 미완료 작업이나 실행 중 콜백이 남았는데 컨텍스트가 사라졌다면 조기 해제입니다. 종료 테스트에서 이 두 실패를 모두 탐지하겠습니다.

02

득점 포인트

이해가 드러나는 지점을 확인해 보세요.

  • 새 유입 차단·미완료 I/O drain·워커 종료·포트 해제의 의존성을 정한다.
  • 종료 패킷과 실제 완료 큐 drain 조건을 구분한다.
  • 완료 중 재제출을 막아 작업 카운터가 다시 증가하지 않게 한다.
  • deadline과 강제 종료가 메모리 수명 보장을 대신하지 못함을 설명한다.
03

감점 포인트

놓치기 쉬운 조건과 오해를 짚어 보세요.

  • 포트를 먼저 닫으면 커널 작업과 완료 컨텍스트가 자동 정리된다고 말한다.
  • 종료 패킷을 받는 즉시 워커가 반환해 남은 I/O를 버린다.
  • 시간 초과를 근거로 OVERLAPPED와 버퍼를 강제 해제한다.
04

더 파고들 거리

하나 더 질문하며 이해의 범위를 넓혀 보세요.

득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.

원리부터 공부하고 싶다면

답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.

← 전체 질문 보기