C++ IOCP 서버 2. IOCP 이론
* 아직 배우고 있는 학생이라 틀린 내용이 있을 수도 있습니다. 틀린 내용이 있다면 알려주시면 감사하겠습니다.
IOCP는 Window 환경에서 작동하는 제일 흔히 쓰이는 논블로킹 프로세스이다.
최소한의 쓰레드로 최대한의 효율을 뽑을 수 있다고 하는데 좀 더 자세히 살펴보았다.
먼저 이름의 뜻부터 살펴보자. IOCP는 IO Completion Port의 약자로 입출력 완료 포트라는 뜻이다.
여기서 사용하는 Port는 통신에서 사용하는 포트와 비슷한 의미로 어떤 항구, 그러니까 목적지라는 의미이다.
하지만 직접적으로 통신에서 사용하는 포트와는 전혀 다른 포트로 처음 공부할 때는 혼란이 올 수도 있다.
1. 비동기 I/O 시작
동기 함수(Connect Close Accept Send)과 같은 역할을 하는 비동기 함수들(AccpetEX, WSASend, WSARecv...)을 실행해서 윈도우 I/O에 넘긴다. 이 동작을 거친 뒤에는 프로그램의 흐름이 다시 호출한 쓰레드로 바로 돌아온다. (비동기)
2. 비동기 입출력 완료
비동기 입출력이 윈도우 I/O에서 종료되면 IOCP라는 항구(Port)에 쌓이게 되는데 이 쌓이는 자료구조는 Queue 이다.
3. GetQueuedCompletionStatus
쓰레드 중에서 작업이 끝난, 그러니까 할 일이 없는 쓰레드에서 GetQueuedCompletionStatus를 호출하면 IOCP에서 완료된 내용을 꺼내서 받을 수 있다.
처음에는 무척 어려운 개념이었는데 순서대로 차근차근 보다 보면 어느새 이해가 됐다.
여기서 사용하는 또 다른 개념? 용어들이 몇 개가 있다.
1. 작업자 쓰레드(Worker Thread)
[IOCP 흐름] 그림에서 여러 개의 쓰레드가 존재하는데 IOCP에서는 이 쓰레드를 작업자 쓰레드라고 부른다.
2. Overlapped
Overlapped는 본래 IOCP가 아닌 Overlapped 모델에서 사용하는 구조체이다.
이 구조체를 이해하기 위해서는 Overlapped 모델에 대한 설명을 한번 읽어보는 것이 좋다.
Overlapped 모델에 대한 설명 = https://www.joinc.co.kr/w/Site/win_network_prog/doc/overlapped
좀 더 간단하게 표현하자면 아래와 같다.
비동기 Recv()를 예로 들자면
1. Overlapped을 초기화(비워줌)해서 넘겨줌.
2. Window I/O에서 Overlapped의 비동기 입출력 결과(위 그림에서는 완료?)와 버퍼가 채워짐.
3. Recv()의 결과를 받는 부분에서 채워진 결과를 토대로 처리.
와 같은 방식으로 사용된다.
Overlapped는 사용자가 커스터마이징이 가능해서 나는 Overlapped에 Player의 정보를 같이 담아서 보내고, 수신받을 때 결과를 분석하는 데 사용하였다.
이 정도면 아주 기본적인(??) IOCP에 대한 내용을 정리한 것 같다.
다음 포스팅에서는 실제로 IOCP를 사용하여 졸작 서버를 어떻게 구현했는지에 대한 포스팅을 하도록 해야겠다.