从网上整理的文章,同样,这只是为了我增加理解记忆而做到得笔记,
不存在利用价值,纯粹是学习和记忆.抄袭也好学习也好只是让人明
白道理.主要干活的还是自己的程序.

I/O设备处理必然让主程序停下来干等I/O的完成,
对这个问题有

方法一:使用另一个线程进行I/O。这个方案可行,但是麻烦。

方法二:使用overlapped I/O。
  正如书上所说:“overlapped I/O是WIN32的一项技术,
    你可以要求操作系统为你传送数据,并且在传送完毕时通知你。
    这项技术使你的程序在I/O进行过程中仍然能够继续处理事务。
    事实上,操作系统内部正是以线程来I/O完成overlapped I/O。
    你可以获得线程的所有利益,而不需付出什么痛苦的代价”。

怎样使用overlapped I/O:

进行I/O操作时,指定overlapped方式
使用CreateFile (),将其第6个参数指定为FILE_FLAG_OVERLAPPED,
就是准备使用overlapped的方式构造或打开文件;
如果采用 overlapped,那么ReadFile()、WriteFile()的第5个参数必须提供一个指针,
指向一个OVERLAPPED结构。 OVERLAPPED用于记录了当前正在操作的文件一些相关信息。

//功能:从指定文件的1500位置读入300个字节
int main()
{
    BOOL rc;
    HANDLE hFile;
    DWORD numread;
    OVERLAPPED overlap;
    char buf[512];
    char szPath=”x:\\xxxx\xxxx”;
   
    //检查系统,确定是否支持overlapped,(NT以上操作系统支持OVERLAPPED)
    CheckOsVersion();
    // 以overlapped的方式打开文件
    hFile = CreateFile( szPath,
                    GENERIC_READ,
                    FILE_SHARE_READ|FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_OVERLAPPED,
                    NULL
                );

// OVERLAPPED结构实始化为0
    memset(&overlap, 0, sizeof(overlap));
    //指定文件位置是1500;
    overlap.Offset = 1500;
   
    rc = ReadFile(hFile,buf,300,&numread,&overlap);
    //因为是overlapped操作,ReadFile会将读文件请求放入读队列之后立即返回(false),
    //而不会等到文件读完才返回(true)
    if (rc)
    {
       //文件真是被读完了,rc为true
       // 或当数据被放入cache中,或操作系统认为它可以很快速地取得数据,rc为true
    }
    else
    {
        if (GetLastError() == ERROR_IO_PENDING)
        {//当错误是ERROR_IO_PENDING,那意味着读文件的操作还在进行中
         //等候,直到文件读完
            WaitForSingleObject(hFile, INFINITE);
            rc = GetOverlappedResult(hFile,&overlap,&numread,FALSE);
            //上面二条语句完成的功能与下面一条语句的功能等价:
            // GetOverlappedResult(hFile,&overlap,&numread,TRUE);
         }
         else
         {
            //出错了
        }
    }
    CloseHandle(hFile);
    return EXIT_SUCCESS;
}

在实际工作中,若有几个操作同一个文件时,
怎么办?我们可以利用OVERLAPPED结构中提供的event来解决上面遇到的问题。
注意,你所使用的event对象必须是一个MANUAL型的;否则,可能产生竞争条件。
原因见书P159。
int main()
{
    int i;
    BOOL rc;
    char szPath=”x:\\xxxx\xxxx”;
    // 以overlapped的方式打开文件
    ghFile = CreateFile( szPath,
                    GENERIC_READ,
                    FILE_SHARE_READ|FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_OVERLAPPED,
                    NULL
                );
    for (i=0; i<MAX_REQUESTS; i++)
    {
        //将同一文件按几个部分按overlapped方式同时读
        //注意看QueueRequest函数是如何运做的,每次读16384个块
        QueueRequest(i, i*16384, READ_SIZE);
    }
    // 等候所有操作结束;
    //隐含条件:当一个操作完成时,其对应的event对象会被激活
    WaitForMultipleObjects(MAX_REQUESTS, ghEvents, TRUE, INFINITE);
    // 收尾操作
    for (i=0; i<MAX_REQUESTS; i++)
    {
        DWORD dwNumread;
        rc = GetOverlappedResult(
                                ghFile,
                                &gOverlapped[i],
                                &dwNumread,
                                FALSE
                            );
        CloseHandle(gOverlapped[i].hEvent);
    }
    CloseHandle(ghFile);
    return EXIT_SUCCESS;
}

//当读操作完成以后,gOverlapped[nIndex].hEvent会系统被激发
int QueueRequest(int nIndex, DWORD dwLocation, DWORD dwAmount)
{
    //构造一个MANUAL型的event对象
    ghEvents[nIndex] = CreateEvent(NULL, TRUE, FALSE, NULL);
    //将此event对象置入OVERLAPPED结构
    gOverlapped[nIndex].hEvent = ghEvents[nIndex];
    gOverlapped[nIndex].Offset = dwLocation;
    for (i=0; i<MAX_TRY_COUNT; i++)
   {
      //文件ghFile唯一
       rc = ReadFile(ghFile, gBuffers[nIndex],&dwNumread,&gOverlapped[nIndex]);
       if (rc)
         return TRUE;
       err = GetLastError();
       if (err == ERROR_IO_PENDING)
       {
           //当错误是ERROR_IO_PENDING,那意味着读文件的操作还在进行中
          return TRUE;
       }
       // 处理一些可恢复的错误
       if ( err == ERROR_INVALID_USER_BUFFER ||
            err == ERROR_NOT_ENOUGH_QUOTA ||
            err == ERROR_NOT_ENOUGH_MEMORY )
        {
           sleep(50);
           continue;//重试
        }
        // 如果GetLastError()返回的不是以上列出的错误,放弃
        break;
    }

return -1;

}

overlapped I/O的学习笔记相关推荐

  1. Windows驱动开发学习笔记(四)—— 3环与0环通信(常规方式)

    Windows驱动开发学习笔记(四)-- 3环与0环通信(常规方式) 设备对象 创建设备对象 设置数据交互方式 创建符号链接 IRP与派遣函数 IRP的类型 其它类型的IRP 派遣函数 派遣函数注册位 ...

  2. VC++深入详解学习笔记

    VC++深入详解学习笔记 Lesson1: Windows程序运行原理及程序编写流程 Lesson2: 掌握C++基本语法 Lesson3: MFC框架程序剖析 Lesson4: 简单绘图 Lesso ...

  3. 【学习笔记5】管道通信:命名管道

    目录 一.前言 二.基本概念 三.命名管道的创建和使用 3.1 函数原型 3.1.1 CreateNamedPipe 3.1.2 ConnectNamedPipe 3.1.3 WaitNamedPip ...

  4. Apollo源码剖析学习笔记2

    Apollo 源码剖析学习笔记2 Talker-ListenerNode 目录中包含了 Node 对象.Reader 对象和 Writer 对象.Node 对象主要对应 Ros 中的 Node 节点, ...

  5. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  6. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  7. 容器云原生DevOps学习笔记——第二期:如何快速高质量的应用容器化迁移

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  8. 2020年Yann Lecun深度学习笔记(下)

    2020年Yann Lecun深度学习笔记(下)

  9. 2020年Yann Lecun深度学习笔记(上)

    2020年Yann Lecun深度学习笔记(上)

最新文章

  1. 鳗鱼劈断后下半身还能运动,机器人:拿来吧你丨Science子刊封面
  2. 设计模式之单例模式实践
  3. 计算机二级mysql模拟_2017年计算机二级MySQL考前模拟练习
  4. springfox源码_Spring boot整合Springfox在线生成restful的api doc
  5. JavaScript中数组交集的最简单代码
  6. 【李宏毅2020 ML/DL】P52 Network Compression - Network Pruning
  7. php数组排序不要用函数,PHP数组排序函数使用方法
  8. linux 进程内存 limit,Linux 中的Soft limit 和Hard limit
  9. api-gateway实践(01)服务网关 - 原型功能
  10. Atitit. 提升开发效率与质量DSL ( 3) ----实现DSL的方式总结
  11. matlab实现模拟退火算法
  12. 安信可IDE 1.5编译ESP8266 RTOS 3.0
  13. python图片转gif
  14. 思维固化,addTarget难道就只能给self
  15. css设置背景颜色的亮度
  16. 466. 统计重复个数
  17. 使用信锐无线控制器对接营运商portal服务器的原理分析与排错
  18. 修复ASUS in WinRE教程
  19. 用C语言程序算交税,用C语言编写函数InComeTax计算七级累进税率的税后收入
  20. 什么是运维?运维开发需要做哪些事情?

热门文章

  1. 漫谈php框架之中间件
  2. 初始化列表的使用(十五)
  3. Redis API的原子性分析
  4. 从Linux内核中获取真随机数【转】
  5. 小心愿 要有真我新格调
  6. Android开发:关于WebView
  7. phpStorm无法使用svn1.8的解决办法
  8. debian6更新网卡驱动
  9. 面向对象的 JavaScript 编程及其 Scope 处理
  10. hihoCoder 网络流四·最小路径覆盖