第十章 同步和异步设备I/O
1.打开和关闭设备对象
打开设备
CreateFile CreateMailslot CreateNamedPipe CreatePipe
关闭设备
CloseHandle CloseSocket
查看设备类型
GetFileType
2.文件设备
Code example:
HANDLE hFile = CreateFile(...);
BYTE pb[10];
DWORD dwNumBytes;
ReadFile(hFile1, pb, 10, &dwNumBytes, NULL);
LARGE_INTEGER liDistanceToMove;
liDistanceToMove.QuadPart = 1024;
SetFilePointerEx(hFile, liDistanceToMove, NULL, FILE_BEGIN);
SetEndOfFile(hFile);
CloseHandle(hFile);
3.同步设备I/O
ReadFile
仅当设备以GENERIC_READ方式打开时才可调用ReadFile
WriteFile
仅当设备以GENERIC_WRITE方式打开时才可调用WriteFile
FlushFileBuffers
强迫系统将缓冲区的数据写设备。
CancelSynchronousIo
如果某个线程因等待I/O操作而挂起太长时间,可以调用该函数使线程从I/O操作中返回。GetLastError可以取得错误代码。
该线程必须符合以下两个条件中的一个:
(1)该线程是则CreateThread或_beginThread函数创建
(2)该线程则OpenThread创建且具有THREAD_TERMINATE权限
I/O设备Cancel请求操作最终则设备驱动实现。若设备驱动不支持I/O Cancel.那么CancelSynchronouslo永远返回True.
4.异步设备I/O基本概念
(1)异步请求要求用CreateFile以FILE_FLAG_OVERLAPPED和OVERLAPPED结构体为参数打开设备,
(2)OVERLAPPED(重迭)结构体
typedef struct _OVERLAPPED
{
DWORD Internal; // [out] Error code
DWORD InternalHigh; // [out] Number of bytes transferred
DWORD Offset; // [in] Low 32-bit file offset
DWORD OffsetHigh; // [in] High 32-bit file offset
HANDLE hEvent; // [in] Event handle or data
} OVERLAPPED, *LPOVERLAPPED;
OVERLAPPED的意思是线程执行I/O请求的时间与线程执行其它任务的时间是重迭的。
该结构体用于指定读、写文件时的起始地址,也就是读、写文件时的偏移值。该偏移值(64位)由Offset和OffsetHigh共指定。
该结构体在使用时一定要先初始化其中三个变量Offset, OffsetHigh, and hEvent
HasOverlappedIoCompleted宏用于判断I/O请求是否执行完毕
(3)取消异步请求
BOOL CancelIo(HANDLE hFile);
BOOL CancelIoEx(HANDLE hFile, LPOVERLAPPED pOverlapped);.
5.获取I/O操作完毕通知
有以下四种方法:
(1)通过设备内核对象获取通知
设备对象也是内核对象。在调用ReadFile或WriteFile时,设备对象会被置成Non-Signal状态。当完成读、写操作后设备对象会被置成Signal状态。
因此可以用WaitForSingleObject WaitForMultipleObject获取I/O操作完毕的通知。
(2)事件内核对象
OVERLAPPED结构体中有一个成员是Event对象的句柄。当I/O操作完毕后 相应的OVERLAPPED对象中Event对象句柄所指向的对象也会被置成Signal状态。
因此,当同时有多个I/O异步请求时,通过WaitForMultipleObject等待每个I/O操作中所对应的OVERLAPPED对象的Event句柄即可获得I/O操作完毕的通知。
6.Common API
CreateFile CreateMailslot CreateNamedPipe CreatePipe
GetFileType