728x90

중첩 I/O의 구현

- I/O를 할 리소스(파일, 파이프 등)을 만들 때 FILE_FLAG_OVERLAPPED를 인자로 주고 I/O를 하는데 OVERRAPED 구조체의 내용으로 비동기 I/O로 진행을 하고 I/O 연산이 끝나면 Event가 Signaled 상태로 바뀜

- 중첩 I/O에 대한 정보를 가지고 있는 구조체

    -> 완료 루틴 I/O는 중첩 I/O의 확장이므로 이 구조체를 초기화하여 사용

typedef struct _OVERLAPPED {
  ULONG_PTR Internal;
  ULONG_PTR InternalHigh;
  union {
    struct {
      DWORD Offset;
      DWORD OffsetHigh;	
    } DUMMYSTRUCTNAME;
    PVOID Pointer;
  } DUMMYUNIONNAME;
  HANDLE    hEvent;		// I/O가 끝났을 때 알려주는 EVENT
} OVERLAPPED, *LPOVERLAPPED;

OVERLAPPED overlappedInst;
memset(&overlappedInst, 0, sizeof(overlappedInst));			// 초기화
overlappedInst.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);	// 이벤트 생성

- I/O에 사용될 리소스(파이프, File 등등)에 인자에 FILE_FLAG_OVERLAPPED 상수 추가

HANDLE CreateNamedPipeA(
  LPCSTR                lpName,
  DWORD                 dwOpenMode,
  DWORD                 dwPipeMode,
  DWORD                 nMaxInstances,
  DWORD                 nOutBufferSize,
  DWORD                 nInBufferSize,
  DWORD                 nDefaultTimeOut,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes
);

HANDLE hPipe;

hPipe = CreateNamedPipe(
	pipeName,
    PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,	// FILE_FLAG_OVERLAPPED 상수를 넣어야 함
    PIPE_TYPE_MESSAGE |
    PIPE_READMOD_MESSAGE | PIPE_WAIT,
    PIPE_UNLIMITED_INSTANCES,
    BUF_SIZE/2,
    BUF_SIZE/2,
    20000,
    NULL
);

- I/O 함수의 Overlapped 인자 부분에 OVERLAAPED 구조체 전달

BOOL WriteFile(
  HANDLE       hFile,
  LPCVOID      lpBuffer,
  DWORD        nNumberOfBytesToWrite,
  LPDWORD      lpNumberOfBytesWritten,
  LPOVERLAPPED lpOverlapped
);

WriteFile(hPipe, dataBuf, bityWrite, &biteWritten, &overlappedInst);

- 비동기 I/O는 Writefile 함수를 실행해도 전송한 데이터를 얻을 수 없음

    -> WritFile 함수를 호출되는 순간이 I/O 연산이 끝나는 시점이 아니기 때문

    -> GetOverlappedResult 함수를 통해 확인

BOOL GetOverlappedResult(
  HANDLE       hFile,
  LPOVERLAPPED lpOverlapped,
  LPDWORD      lpNumberOfBytesTransferred,
  BOOL         bWait
);

GetOverlappedResult(hPipe, &overlappedInst, &bytesTransfer, FALSE);

 

완료 루틴 I/O의 구현

- 중첩 I/O에 완료 루틴 함수를 추가

- I/O 연산이 끝나면 호출되는 함수가 추가되어 연관 관계를 구성

- 완료 루틴이 호출되면 I/O 연산이 끝났다는 것을 알 수 있기 때문에 Overlappaed 구조체의 event 핸들이 필요없어짐

- 여기서 I/O 함수는 Ex가 뒤에 오는 함수를 사용(WriteFileEx, ReadFileEx)

BOOL WriteFileEx(
	HANDLE file,
    LPCVOID lpBuffer,
    DWORD nNUmberOfBytesToWrite,
    LPOVERLAPPED lpOverlapped,
    LPOVERLAPPED_COMPLETION_ROUTINE		// 완료 루틴에 사용할 함수
);

- 완료 루틴

    -> 함수가 호출하는 대상이 사용자가 아닌 Windows에 의해서 자동적으로 호출

    -> 함수를 선언하면 전달 인자도 Windows가 전달해줌

void CALLBACK FileIOCompletionRoutine(
  DWORD dwErrorCode,
  DWORD dwNumberOfBytesTransfered,
  LPOVERLAPPED lpOverlapped
)

- Overlapped 구조체의 event 핸들에 임의의 데이터를 입력하여 완료루틴에서 사용할 데이터로 활용

728x90

+ Recent posts