중첩 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 핸들에 임의의 데이터를 입력하여 완료루틴에서 사용할 데이터로 활용
'Programming > System Programming' 카테고리의 다른 글
윈도우즈 시스템 프로그래밍 - 20. 메모리 관리(1) (0) | 2020.08.23 |
---|---|
윈도우즈 시스템 프로그래밍 - 19. 비동기 I/O와 APC(4) (0) | 2020.08.22 |
윈도우즈 시스템 프로그래밍 - 19. 비동기 I/O와 APC(2) (0) | 2020.08.19 |
윈도우즈 시스템 프로그래밍 - 19. 비동기 I/O와 APC(1) (0) | 2020.08.18 |
윈도우즈 시스템 프로그래밍 - 18. 파일 I/O와 디렉토리 컨트롤(2) (0) | 2020.08.17 |