IOCP의 사용 이유
다중접속 서버의 구현에 있어서 가장 문제는 클라이언트 하나당 하나의 소켓과 쓰레드를 할당하여 연결해 주어야 하는것이다. 여러 클라이언트가 접속시 서버는 각각의 쓰레드를 생성해야한다.
이때 context switching이 발생하며 이는 상당한 부하를 발생시킨다.
1. IOCP는 기본적으로 비동기 입출력 모델이다(Overlapped IO)
2. 제한된 쓰레드의 수를 통해서, 여러소켓의 입출력을 담당하게 한다.
3. 컨텍스트 스위칭에 소비되는 시간을 최소화 시키는 모델이다.
4. Overlapped 입출력 모델의 특징과 비동기 Notification 입출력 모델의 특징을 동시에 지닌다.
(비동기 Notification 입출력 모델과는 적용 시점에 차이가 있다.)
비동기 입출력 (소켓에 이벤트가 발생되었는가를 확인하기 위해 소켓을 감시한다. 소켓에 어떠한 이벤트가 발생을 했다. 상황을 인식하고 입출력을 진행한다.)
IOCP 입출력 (입출력을 Overlapped방식을 사용하여 진행을 하고. 입출력이 완료가 된다면 어떠한 이벤트가 발생했는가를 확인한다.)
전체적인 구조
Completion Port를 생성한다. Completion Port는 여러개의 소켓과 연결되어 관리를 한다.
생성시 Completion Queue가 생성되며 비동기 입출력이 완료가 되었을시 Completion Port는 알게된다. Completion Port는 완료 소켓에 관한 패킷을 하나 생성하여 Queue에 Push시켜준다. 쓰레드에서는 Completion Queue를 확인하여 Queue가 비어있다면 대기하고, 정보가 있다면 가져온다.
Queue에 있는 입출력이 완료된 패킷을 가져오는 일을 하는 쓰레드를 워커 쓰레드 라고 한다.
1. Completion Port 오브젝트의 생성
CreateIoCompletionPort 마지막 인자는 동시 실행한 가능한 쓰레드의 수를 결정 지어주는 수를 신경써서 넘겨주어야 한다.
0을 인자로 전달시 현제 내 시스템에 장착되어 있는 수 만큼 쓰레드의 수를 결정 짖겠다는 의미이다. (최대한 효율적으로 시스템을 운영 하겠다. )
2. Completion Port 오브젝트와 소켓의 연결
첫번째 인자인 연결 시킬 소켓 핸들(A)과, 두번째 인자인 연결 시킬 Completion Port의 핸들(B)을 연결 시킨다.
A와 B가 연결 되었다. A의 입출력이 완료 되었다면 B의 Queue에 패킷을 만들어 넣어 줄 것이다. 이 경우 3번째 인자를 사용하여
Queue에 담겨지는 패킷에 추가로 인자를 추가할때 사용한다. 워커 쓰레드는 입출력 완료에 따른 상세한 정보를 얻을 수 있다.
3. GetQueuedCompletionStatus 함수
위의 A와 B가 연결 되어있다면 B가 감지하여 입출력이 완료 되었다면 감지하여 패킷을 만들고 Queue에 넣어준다.
Completion Queue에 입출력이 완료된 패킷 정보가 있다면 그 정보를 꺼내오는 함수이다.
꺼내올 Completion Port를 첫 번째 인자로 넘겨준다. 2 3 4번째 인자를 통해 패킷 내부에 있는 데이터를 얻어오게 된다.
2번째 인자를 통해서 전체 크기를 받고, 3번째 인자를 통해서 추가적으로 추가한 데이터를 얻는다.
GetQueuedCompletionStatus 함수를 쓰레드 내부에서 호출 하면 자동으로 SLEEP 상태가 되면서 IOCP 가 내부적으로 관리하는
쓰레드풀로 들어가게 된다.
Queue가 NULL 이라면 블로킹 상태에 놓인다 따라서 쓰레드는 SLEEP 상태에 놓이게 된다.
즉 IO Complete Queue에서 데이터 하나를가 들어오면 IOCP가 쓰레드 중 하나를 깨우고 처리하고 나서 다시 이 함수를 부름 다시 정리하면 이 함수가 불리기전엔 해당 스레드가 대기 상태라서 CPU를 잡아 먹지 않는다.
--------------------
서버를 만든다고 해도 사용하지 않으면 잊혀지기 마련... IOCP가 클라이언트 다중 접속 관련 비동기 처리 방식인데.. 스레드풀로 스레드 관리하면서 워킹스레드인지 프리스레드 인지 ... 컨텍스트 스위칭...
기억이 가물가물해 간단히 정리 된 자료 올려보았음.
'[ Programing ] > Server' 카테고리의 다른 글
UDP 홀펀칭2 (0) | 2013.08.22 |
---|---|
UDP 홀펀칭 (0) | 2013.08.22 |
뮤텍스와 세마포어 (0) | 2013.08.22 |
이벤트 객체 CreateEvent, SetEvent, ResetEvent, PulseEvent (0) | 2012.12.04 |
Shared memory (0) | 2010.07.23 |