Windows异步I/O读文件的缓存限制问题?

luckysym 2010-11-07 07:12:42
在Windows下,使用OVERLAPPED方式,读取一个大文件(TEST.DAT, 200MB),示例代码如下(缩减):

HANDLE file_handle = 0;
DWORD numb_of_bytes = 0;
CHAR * file_buffer = new CHAR[1024 * 1024 * 128];
DWORD bytes_to_read = 1024 * 1024 * 64;
OVERLAPPED overlapped;

file_handle = CreateFile(
_T("D:\\TEST.DAT"),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED
NULL);

overlapped.Internal = 0;
overlapped.InternalHigh = 0;
overlapped.Offset = 0;
overlapped.OffsetHigh = 0;
overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

BOOL result = ReadFile(file_handle, (void*)file_buffer, bytes_to_read, NULL, &overlapped);
result = GetOverlappedResult(file_handle, &overlapped, &numb_of_bytes, 60 * 1000);

.....


运行后发现:

(1)如果bytes_to_read < 64M字节,文件正常读取,numb_of_bytes输出值为64M字节。
(2)如果bytes_to_read >= 64M字节,那么GetOverlappedResult函数将等待到超时,并且numb_of_bytes输出为0。且在Windows任务管理器的进程IO读取字节中,同样显示为0。
(3)如果采用同步方式,则不存在上述现象,无论bytes_to_read多大,文件都将正常读取,且numb_of_bytes输出值正常。
(4)Win32SDK文档中,关于File I/O有一章File Caching,其中建议对于大数据量读写,最好使用FILE_FLAG_NO_BUFFING参数选项,但经测试,使用该选项时,结果与上述情况相同。

推测:

对于异步I/O,Windows内核设置了最大读取数据量的限制,以避免一个I/O长时间占用I/O通道,这个限制就在64MB。


不知上述推测是否属实,或者是哪里设置问题,查阅多方文档,均未解。
...全文
151 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhanshen2891 2010-11-08
  • 打赏
  • 举报
回复
刚刚做了测试,开始的时候确实是64MB总是返回0,lasterror是系统资源不足。但是后来我把请求的字节数减少,开始减少到64MB - 256KB,可以正常读取了,然后我又改为64MB - 128KB第一次为0,第二次就可以正常读取了,用同样的办法一直增加到68MB了,还是可以正常读取了。但是如果一下增加到128MB还是不行,似乎是缓慢的一点一点增加就可以!

不知道是不是有个分配策略?
luckysym 2010-11-08
  • 打赏
  • 举报
回复
自己顶一下子,期待牛人解答

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧