异步设备io基础:
与其他操作相比,设备io是其中最慢的、最不可预测的操作之一。使用异步设备I/O可以更好的使用资源,并创建出更高效的应用程序。
异步I/O的更高效体现:一个线程发一个异步I/O请求,这个I/O请求被传给一个设备驱动程序,负责完成I/O的实际操作。当这个驱动程序等待设备响应的使用,线程并没有因此而被挂起,线程会运行其他有用的任务。
异步I/O实现方法
1.异步的方式访问设备,需将CreateFile中dwFlgsAndAttributes参数指定FILE_FLAG_OVERLAPPED标志。告诉计算机我们要以异步的方式访问设备。
2.将I/O请求加入设备驱动程序队列,比如使用ReadFile和WriteFile函数
BOOL ReadFile(
HANDLE hFile, //读取的设备句柄
PVOID pvBuffer, //缓冲区,存取内容的内存
DWORD nNumBytesToRead, //读取内容的大小
PDWORD pdwNumBytes, //以传输的字节数
OVERLAPPED* pOverlapped); //异步io的完成是的相关数据
BOOL WriteFile(
HANDLE hFile, //读取的设备句柄
PVOID pvBuffer, //缓冲区,存取内容的内存
DWORD nNumBytesToRead, //读取内容的大小
PDWORD pdwNumBytes, //以传输的字节数
OVERLAPPED* pOverlapped); //异步io的完成是的相关数据
提醒:当这两个函数执行异步I/O的时候会直接返回结果,不需等待I/O操作完成,所以pdwNumBytes可以(也通常会)传入NULL给pdwNumBytes。那么有关I/O操作的信息就在pOverlapped这个参数所指向的内存中了,如果是同步I/O操作,pOverlapped参数传入NULL。
I/O完成端口GetQueuedCompletionStatus:
这个强制转换啥也没做,只是欺骗一下编译器说,
这个数据(指针)lpPipeInst
其实是那个LPOVERLAPPED (OVERLAPPED*)类型的。
而OVERLAPPED 类型的数据,是 PIPEINST这个结构的第一个域,
所以*lpPipeInst这个结构对象的地址,和他的第一个域的地址数值相同,只是类型不同。
习惯性的强制转化一下,写成(LPOVERLAPPED) lpPipeInst, ,
其实改成 &lpPipeInst->oOverlap 也不是不行