IOCP 의 단계적 구현  시스템프로그래밍 

2015.08.02. 12:48

복사http://blog.naver.com/pwk0810/220438678355

전용뷰어 보기

+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 의 진행대상인 소켓의 핸들을 배열에 저장해 놓고 , 관리할 필요가 없다.

 


Posted by 뉴암스테르담
l