Thread를 사용하지 않고도 비동기적으로 IO 데이터를 받을 수 있음
HANDLE hFile = CreateFile(
fileName,
GENERIC_READ, // RW 설정
0,
NULL,
OPEN_EXISTING, // 이미 존재하거나, 존재하지 않는 파일에 대한 작업 방법
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, // Overlapped 설정 시 비동기 IO
NULL);
BOOL ret = ::ReadFile(
hFile,
pOffsetData, // Buffer의 시작 위치
size, // 읽을 데이터의 양
&dwRead, // 읽은 데이터의 양 반환
&readOV // overlapped 되어있을 경우 그에 대한 정보를 반환한다고는 하는데.. 잘은 모르겠음
);
if(GetLastError() == ERROR_IO_PENDING)
// 아직 IO 작업 중
{ ... }
ret = ::GetOverlappedResult(hFile, &readOV, &dwRead, FALSE); // IO 완료 시 TRUE 반환
GetOverlappedResult()를 통해 LPOverlapped를 반환받더라도 즉각적인 IO 진행상황을 받아오진 못한다
만약 진행 상황을 알고싶다면 거대한 데이터를 잘게 쪼개서 IO 작업을 하는것이 더 좋음
AIO를 찾아보면 IO과정에는 CPU 사용률이 많이 떨어지므로 이 과정을 kernel에서 수행하고 그 동안 CPU는 다른 작업을 수행함으로써 CPU 사용률을 끌어올리는 기법이라는 설명을 많이 볼 수 있음
그러나 Kernel도 결국 명령 처리를 위해서는 CPU의 decopile이 필요할 것이므로 과연 AIO와 Background IO를 통한 차이가 무엇인지에 대해 궁금해졌음
위키피디아와 MSDN을 찾아보면 AIO는 interrupt를 이용한다는 것을 알 수 있음
이러한 관점에서 Kernel이 IO명령을 받으면 HDD Device Driver같은 곳에 IO, from, count같은 명령어와 매개변수만 던져주면 Device Driver가 독립적으로 IO를 수행한 후 작업이 완료되면 Interrupt를 통해 Kernel에 알리는 것이 아닌가라는 가정을 세우게 되었음
다음 자료를 보면 그 가정이 맞는것으로 보임
결국 AIO는 Kernel mode에서 device driver에서 독립적으로 수행할 명령을 던져주고, IO과정에서 지연될 시간동안 User가 독자적으로 작업을 수행함으로써 CPU 효율을 올리는 기법이라고 볼 수 있음