Overlapped I/O 在你的身后变戏法
2011-12-01 23:54
162 查看
Overlapped I/O是win32的一项技术,你可以要求操作系统为你传送数据,并且在传送完毕时通知你。事实上,操作系统内部正是以线程来完成overlapped I/O,你可以获得线程的所有利益不需要付出什么代价。
Win32文件操作函数
win32中有3个基本的函数来执行I/O,分别是CreateFile, ReadFile, WriteFile. 关闭文件调用CloseHandle即可。
CreateFile可以用来打开各种资源,包括(不限于)
文件(硬盘,光盘,软盘或其他)
串行口和并行口
Named Pipes
Console
HANDLE CreateFile(
LPCTSTR lpFileName, //文件名称
DWORD dwDesiredAccess, //存取模式,读或写
DWORD dwShareMode, //共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, //安全属性
DWORD dwCreationDisposition, //如何产生
DWORD dwFlagsAndAttributes, //文件属性
HANDLE hTemplateFile //临时文件,将拥有全部的属性拷贝
);
第6个参数dwFlagsAndAttributes是使用overlapped I/O的关键。可以是多个数值组合在一起。对于overlapped I/O关键的是FILE_FLAG_OVERLAPPED。通过这个参数可以指定是同步或者异步访问,不能2个都指定。
overlapped I/O可以同时读或写文件的许多部分,这些操作都使用相同的文件handle。因此,当你使用overlapped I/O时,每个读写操作都要包含文件位置。如果有多个overlapped请求,那么执行的次序无法保证。不能使用标准的C库来实现overlapped 操作,必须要以ReadFile和WriteFile来完成。
BOOL ReadFile(
HANDLE hFile, //欲读的文件
LPVOID lpBuffer, //接受数据的缓冲区
DWORD nNumberOfBytesToRead, // 欲读取的字节个数
LPDWORD lpNumberOfBytesRead, // 实际读取的字节个数的地址
LPOVERLAPPED lpOverlapped // 指针,指向overlapped info结构
);
BOOL WriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
typedef struct _OVERLAPPED {
ULONG_PTR Internal; //通常保留,当GetOverLappedResult返回False时,有用
ULONG_PTR InternalHigh; /通常保留,当GetOverlappedResult返回TRue时,有用
union {
struct {
DWORD Offset; //读写的偏移地址
DWORD OffsetHigh; //64位地址中较高的32位
};
PVOID Pointer;
};
HANDLE hEvent; //一个手动重置的eventuixiang,当overlapped 完成时激发
} OVERLAPPED, *OVERLAPPEDLPOVERLAPPED;
OVERLAPPED的2个功能,识别每一个正在进行的overlapped操作,你和系统之间的共享区域,参数在这个区域中双向传递。
由于OVERLAPPED结构的生命周期超越ReadFile和writeFile,所以要将其放在一个安全的地方,就是heap。
被激发的File Handles
最简单的overlapped I/O类型,是使用它自己的文件handle作为同步机制。首先以FILE_FLAG_OVERLAPPED告诉win32说你不要使用默认的同步IO。然后设立一个OVERLAPPED结构,其中包含“IO请求”的所有必要参数,并以此识别这个IO请求,直到完成为止。接下来,调用ReadFile并以OVERLAPPED结构的地址作为最后一个参数。这时,就可以等待win32为你处理io,你可以做其他的事情了。
如果你需要等待overlapped IO的执行结果,作为WaitForMultipleObjects的一部分,请在handle数组中加上这个文件handle。 当完成操作后,可调用GetOverlappdedResult以确定结果如何。
代码
BOOL WINAPI GetOverlappedResult(
HANDLE hFile, //文件或者设备的handle
LPOVERLAPPED lpOverlapped, //一个指向OVERLAPPED结构的指针
LPDWORD lpNumberOfBytesTransferred, //指针,获得真正传送的字节个数
BOOL bWait //是否要等待操作完成
);
返回值:如果overlapped操作成功,返回TRUE,失败返回FALSE。如果bWait为False而overlapped还没有完成,GetLastError会传回ERROR_IO_INCOMPLETE.
我们要注意,虽然我们要求进行overlapped操作,但如果数据可以很快的传送,那么文件操作就可能会在REadfile返回之前完成,而ReadFile返回TRUE。
如果请求进行overlapped操作,那么ReadFile和WriteFile常规情况下会返回FALSE, 我们必须调用GetLastError并确定它传回ERROR_IO_PENDING,以为着IO操作被放进队列中等待执行。如果是其他返回值,就代表一个真正的错误了。
被激发的Event对象
以文件handle作为激发机制,如果在一个文件上有多个overlapped操作时,无法得知那个overlapped操作完成了。这时,我们可以使用OVERLAPPED结构中的最后一个event handle位,当这个栏位设为一个event对象时,系统核心会在overlapped操作完成时,自动将这个event 对象激发。每个操作都有独一无二的event对象,所使用的event对象必须是手动重置的。
Win32文件操作函数
win32中有3个基本的函数来执行I/O,分别是CreateFile, ReadFile, WriteFile. 关闭文件调用CloseHandle即可。
CreateFile可以用来打开各种资源,包括(不限于)
文件(硬盘,光盘,软盘或其他)
串行口和并行口
Named Pipes
Console
HANDLE CreateFile(
LPCTSTR lpFileName, //文件名称
DWORD dwDesiredAccess, //存取模式,读或写
DWORD dwShareMode, //共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, //安全属性
DWORD dwCreationDisposition, //如何产生
DWORD dwFlagsAndAttributes, //文件属性
HANDLE hTemplateFile //临时文件,将拥有全部的属性拷贝
);
第6个参数dwFlagsAndAttributes是使用overlapped I/O的关键。可以是多个数值组合在一起。对于overlapped I/O关键的是FILE_FLAG_OVERLAPPED。通过这个参数可以指定是同步或者异步访问,不能2个都指定。
overlapped I/O可以同时读或写文件的许多部分,这些操作都使用相同的文件handle。因此,当你使用overlapped I/O时,每个读写操作都要包含文件位置。如果有多个overlapped请求,那么执行的次序无法保证。不能使用标准的C库来实现overlapped 操作,必须要以ReadFile和WriteFile来完成。
BOOL ReadFile(
HANDLE hFile, //欲读的文件
LPVOID lpBuffer, //接受数据的缓冲区
DWORD nNumberOfBytesToRead, // 欲读取的字节个数
LPDWORD lpNumberOfBytesRead, // 实际读取的字节个数的地址
LPOVERLAPPED lpOverlapped // 指针,指向overlapped info结构
);
BOOL WriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
typedef struct _OVERLAPPED {
ULONG_PTR Internal; //通常保留,当GetOverLappedResult返回False时,有用
ULONG_PTR InternalHigh; /通常保留,当GetOverlappedResult返回TRue时,有用
union {
struct {
DWORD Offset; //读写的偏移地址
DWORD OffsetHigh; //64位地址中较高的32位
};
PVOID Pointer;
};
HANDLE hEvent; //一个手动重置的eventuixiang,当overlapped 完成时激发
} OVERLAPPED, *OVERLAPPEDLPOVERLAPPED;
OVERLAPPED的2个功能,识别每一个正在进行的overlapped操作,你和系统之间的共享区域,参数在这个区域中双向传递。
由于OVERLAPPED结构的生命周期超越ReadFile和writeFile,所以要将其放在一个安全的地方,就是heap。
被激发的File Handles
最简单的overlapped I/O类型,是使用它自己的文件handle作为同步机制。首先以FILE_FLAG_OVERLAPPED告诉win32说你不要使用默认的同步IO。然后设立一个OVERLAPPED结构,其中包含“IO请求”的所有必要参数,并以此识别这个IO请求,直到完成为止。接下来,调用ReadFile并以OVERLAPPED结构的地址作为最后一个参数。这时,就可以等待win32为你处理io,你可以做其他的事情了。
如果你需要等待overlapped IO的执行结果,作为WaitForMultipleObjects的一部分,请在handle数组中加上这个文件handle。 当完成操作后,可调用GetOverlappdedResult以确定结果如何。
代码
BOOL WINAPI GetOverlappedResult(
HANDLE hFile, //文件或者设备的handle
LPOVERLAPPED lpOverlapped, //一个指向OVERLAPPED结构的指针
LPDWORD lpNumberOfBytesTransferred, //指针,获得真正传送的字节个数
BOOL bWait //是否要等待操作完成
);
返回值:如果overlapped操作成功,返回TRUE,失败返回FALSE。如果bWait为False而overlapped还没有完成,GetLastError会传回ERROR_IO_INCOMPLETE.
我们要注意,虽然我们要求进行overlapped操作,但如果数据可以很快的传送,那么文件操作就可能会在REadfile返回之前完成,而ReadFile返回TRUE。
如果请求进行overlapped操作,那么ReadFile和WriteFile常规情况下会返回FALSE, 我们必须调用GetLastError并确定它传回ERROR_IO_PENDING,以为着IO操作被放进队列中等待执行。如果是其他返回值,就代表一个真正的错误了。
被激发的Event对象
以文件handle作为激发机制,如果在一个文件上有多个overlapped操作时,无法得知那个overlapped操作完成了。这时,我们可以使用OVERLAPPED结构中的最后一个event handle位,当这个栏位设为一个event对象时,系统核心会在overlapped操作完成时,自动将这个event 对象激发。每个操作都有独一无二的event对象,所使用的event对象必须是手动重置的。
相关文章推荐
- 《Win32多线程程序设计》学习笔记 第6章 Overlapped I/o 在你的身后变戏法
- Overlapped I/O,在你身后变戏法
- Overlapped I/O 在你的身后变戏法
- OVERLAPPED结构
- Winsock I/O系列3: Overlapped I/O
- Overlapped I/O模型--完成例程
- SOCKET编程进阶之Overlapped I/O完成例程模型
- 窗口style--WS_OVERLAPPEDWINDOW 分析
- Winsock学习笔记5:I/O Overlapped (重叠)模式
- 百度与腾讯:站在十亿消费者身后
- 异步IO模型和Overlapped结构
- 【网络编程】之十、重叠IO Overlapped IO
- HTML5--1,html5的生前身后
- 大唐电信的盈利“戏法”
- overlapped I/O的学习笔记
- unity3D游戏开发实战原创视频讲座系列13之帽子戏法游戏开发(预告)
- 异步IO模型和Overlapped结构
- 对话框不显示右上角X号的方法--对话框属性的style改为Overlapped
- MFC窗口style为overlapped popup child三者的区
- OVERLAPPED结构--异步IO