IOCP 2005/11/10
특징 1. 요청과 응답처리를 같은 쓰레드에서 처리하지 않는다. 2. OVERLAPPED-IO에 기반을 두고 있다.(비동기 처리) 3. 쓰레드 풀을 사용한다.(쓰레드 풀의 효율적인 관리) (정해진 수만큼의 쓰레드가 작업을 처리하도록 한다.) *생성한 쓰레드수가 아니다.* 4. Direct-IO 방식 사용 (꼭 IOCP라서 사용하는건 아니라 생각하는데 우선은 그렇다고 함) 5. Socket뿐만아니라, 모든 디바이스 드라이버(?)에 사용할수 있다. (Socket, File)에만 구현되어 있다고 함…
Overlapped IO (1) (2) 여러 개의 I/O 순차적으로 하지 않고 중복해서 요청이 가능하다. I/O를 요청한 TASK와 I/O를 처리하는 쓰레드가 중복해서 처리된다. (2) IO 요청 I/O 완료를 확인하는 방법 1. Event를 이용하는 방법 2. Callback Function 호출을 이용하는 방법-APC(?) 3. 직업물어보는 방법-poll(?)
연결 생성 쓰레드 m_socListen = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED); bind(m_socListen, (LPSOCKADDR)&saServer, sizeof(struct sockaddr)); listen(m_socListen, 5); m_hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, nMaxNumberOfConcurrentThreads); while(true) { clientSocket = WSAAccept(m_socListen, (LPSOCKADDR)&SockAddr, &nLen,0,0); HANDLE h = CreateIoCompletionPort((HANDLE) clientSocket, m_hIOCP, dwCompletionKey, 0); WSARecv(pPerSocketCtx->socket, &(pPerSocketCtx->recvContext->wsaBuf), 1, &dwRecvBytes, &dwFlags, &(pPerSocketCtx->recvContext->overlapped), NULL) }
작업처리 쓰레드 while(true) { BOOL bIORet = GetQueuedCompletionStatus(hCompletionPort, &dwIoSize, (LPDWORD) &lpClientContext, &lpOverlapped, INFINITE); // 얻어온 I/O 정보에 따라서 원하는 정보를 처리합니다. WSARecv(pPerSocketCtx->socket, &(pPerSocketCtx->recvContext->wsaBuf), 1, &dwRecvBytes, &dwFlags, &(pPerSocketCtx->recvContext->overlapped), NULL) }
IOCP와 관련된 중요한 함수들의 ProtoType dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED HANDLE CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); // IOCP객체를 생성, IOCP객체와 CreateFile등과 같은함수에서 나온 FileHandle과여 연결등에 사용한다. HANDLE CreateIoCompletionPort(HANDLE FileHandle, HANDLE ExistingCompletionPort, ULONG_PTR CompletionKey, DWORD NumberOfConcurrentThreads); // IOCP에 의해서 응답을 처리할수 있도록 분리기 위해서 대기 BOOL GetQueuedCompletionStatus(HANDLE CompletionPort, LPDWORD lpNumberOfBytes, PULONG_PTR lpCompletionKey, LPOVERLAPPED* lpOverlapped, DWORD dwMilliseconds); // IOCP Queue에 임으로 Entry를 추가할때 사용 BOOL PostQueuedCompletionStatus(HANDLE CompletionPort, DWORD dwNumberOfBytesTransferred, ULONG_PTR dwCompletionKey, LPOVERLAPPED lpOverlapped); // 파일(장치)에서 내용읽기 BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped); BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); // IOCTL BOOL DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);
참고자료 데브피아 VC++ 이기탁님 강좌 CodeProject – A simple IOCP Server/Client Class MSDN