+Completion port 의 구성
- Accept 함수의 호출은 main 쓰레드가 처리하도록 하고, 별도의 쓰레드를 추가로 하나 생성하여 클라이언트와의 입출력을 담당한다
- 입력과 출력은 non-blocking 모드로 동작하는가?
- non-blocking 모드로 진행된 입력과 출력의 완료는 어떻게 확인하는가?
- IOCP 에서는 완료된 IO 의 정보가 Completion 포트 오브젝트라는 커널 오브젝트에 등록된다.
- " 이 소켓을 기반으로 진행되는 IO 의 완료상황은 저 CP 오브젝트에 등록해 주세요"
- IOCP 모델의 서버 구현에서 진행하여야 하는 일
- Completion Port 오브젝트의 생성
- Completion Port 오브젝트와 소켓의 연결
#include <Windows.h> HANDLE CreateCompletionPort(HANDLE FileHandle, HANDLE ExistingCompletionPort, ULONG_PTR CompletionKey, DWORD NumberofCoucurrentTrheads); CP 오브젝트 생성 |
FileHandle | CP 오브젝트 생성시에는 INAVLID_HANDLE_VALUE 를 전달 |
ExstingCompletionPort | CP 오브젝트 생성시에는 NULL 전달 |
CompletionKey | CP 오브젝트 생성시에는 0 전달 |
NumberOfConcurrentThreads | CP 오브젝트에 할당되어 완료된 IO 를 처리할 쓰레드의 수를 전달 예를 들어 2가 전달되면 CP 오브젝트에 할당되어 동시 실행 가능 한 쓰레드의 수는 최대 2개로 제한한다. 그리고 이 인자에 0이 전달되면 시스템의 CPU 개수가 동시 실행가능한 쓰레드의 최대수로 지정된다. |
HANDLE hCpObject; hCpObject = CreateIOCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 2);
|
+ Completion Port 오브젝트와 소켓의 연결
- 생성된 CP 오브젝트를 소켓과 연결하는 과정이다. 그래야 소켓의 IO 정보가 CP 오브젝트에 등록된다.
#include <Windows.h> HANDLE CreateCompletionPort(HANDLE FileHandle, HANDLE ExistingCompletionPort, ULONG_PTR CompletionKey, DWORD NumberofCoucurrentTrheads); -> 성공시 CP 오브젝트의 핸들 , 실패시 NULL 반환 |
FileHandle | CP 오브젝트에 연결할 소켓의 핸들 전달 |
ExstingCompletionPort | 소켓과 연결할 CP 오브젝트의 핸들 전달 |
CompletionKey | 완료된 IO 관련 정보의 전달을 위한 매개변수 |
NumberOfConcurrentThreads | 어떠한 값을 전달하던 , 이 함수의 두번째 매개변수가 NULL 이 아니면 그냥 무시된다. |
HANDLE hCpObject;
hCpObject = CreateIOCompletionPort(INVALID_HANDLE_VALUE, NULL, 0,
HANDLE hCpObject; SOCKET hSock
CreateIOCompletionPort((HANDLE)hSock, hCpObject, (DWORD) ioIfo, 0); |
+ Completion Port 의 완료된 IO 확인과 쓰레드의 IO 처리
- CP 에 등록되는 완료된 IO 의 확인 방법에 관련된 함수
#include < windows.h> BOOL GetQueueCompletionStatus( HANDLE CompletionPort, LPDWORD lpNumberOfBytes, PULONG_PTR lpCompletionKey, LPOVERLAPPED* lpOverlapped, DWORD dwMilliseconds); |
CompletionPort | 완료된 IO 정보가 등록되어 있는 CP 오브젝트의 핸들 전달 |
lpNumberOfBytes | 입출력 과정에서 송수신된 데이터의 크기 정보를 저장할 변수의 주소값 전달 |
lpCompletionKey | CreateIOCompletionPort 함수의 세번째 인자로 전달된 값의 저장을 위한 변수의 주소값 전달 |
lpOverlapped | WSASend, WSARecv, 함수 호출시 전달하는 OVERLAPPED 구조체 변수의 주소값이 저장될 변수의 주소값 전달 |
dwMilliseconds | 타임아웃 정보 전달, 여기서 지정한 시간이 완료되면 FALSE 를 반환하면서 함수를 빠져나가며, INFINITE 를 반환하면서 함수를 빠져나가며, INFINITE 를 전달하면 완료된 IO 가 CP 오브젝트에 등록될때까지 블로킹 상태에 있게 된다. |
- GetQueuedCompletionStatus 함수의 세번째 인자를 통해서 얻게 되는 것은 소켓과 CP 오브젝트의 연결을 목적으로 CreateIOCompletionPort 함수가 호출될때 전달되는 네번째 인자값이다.
- GetQueuedCompletionStatus 함수의 네번째 인자를 통해서 얻게되는 것은 WSASend, WSARecv 함수 호출시 전달되는
WSAOVERLAPPED 구조체 변수의 주소값이다.
-

+IO 가 성능이 좀 더 나오는 이유
- NON-BLOCKING 방식으로 IO 가 진행되기 때문에, IO 작업으로 인한 시간의 지연이 발생하지 않는다.
- IO 가 완료된 핸들을 찾기 위해서 반복문을 구성할 필요가 없다.
- IO 의 진행대상인 소켓의 핸들을 배열에 저장해 놓고 , 관리할 필요가 없다.