异步IO操作与同步操作区别:

  1. 在CreateFile里的FILE_FLAG_OVERLAPPED标志
  2. 异步操作函数LPOVERLAPPED参数

接收IO请求完成通知

  1. 触发设备内核对象
    缺点:同一个设备内核对象有可能进行多次读写操作,这样第一个完成这个设备内核对象就会被触发,所以这种方式不可以使用于这种情形

    void Test1()
    {
    HANDLE hFile = ::CreateFile(_T("aaa.txt"),
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,
    NULL);
    if(!hFile)
    {
    wcout<<L"CreateFile Failed ErroCode:"<<::GetLastError()<<endl;
    return ;
    }
    DWORD dwFileSize = ::GetFileSize(hFile,);
    wcout<<L"FileSize:"<<dwFileSize<<endl;
    char * pFileContent = new char[];
    DWORD dwReaded = ;
    OVERLAPPED o_Read = {};
    DWORD bReadDone = ::ReadFile(hFile,
    pFileContent,
    ,
    &dwReaded,
    &o_Read);
    DWORD dwError = ::GetLastError();
    if(!bReadDone && (dwError == ERROR_IO_PENDING))
    {
    WaitForSingleObject(hFile,INFINITE);
    bReadDone = TRUE;
    } if(bReadDone)
    wcout<<L"I/O Code:"<<o_Read.Internal<<" TransedBytes:"<<o_Read.InternalHigh<<endl;
    else
    wcout<<"Error:"<<::GetLastError()<<endl;
    ::CloseHandle(hFile);
    delete [] pFileContent;
    }
  2. 触发事件内核对象
    void Test2()
    {
    HANDLE hFile = ::CreateFile(_T("aaa.txt"),
    GENERIC_WRITE,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,
    NULL);
    if(!hFile)
    {
    wcout<<L"CreateFile Failed ErroCode:"<<::GetLastError()<<endl;
    return ;
    }
    DWORD dwFileSize = ::GetFileSize(hFile,);
    wcout<<L"FileSize:"<<dwFileSize<<endl;
    LARGE_INTEGER liDis = {};
    LARGE_INTEGER liRet = {};
    ::SetFilePointerEx(hFile,liDis,&liRet,FILE_END);
    wcout<<L"PreWrite File Pos:"<<liRet.LowPart<<endl;
    char * pFileContent = new char[];
    memset(pFileContent,'z',);
    DWORD dwReaded = ;
    OVERLAPPED o_Write = {};
    o_Write.Offset = liRet.LowPart;
    o_Write.hEvent = ::CreateEvent(NULL,FALSE,FALSE,NULL);
    DWORD bReadDone = ::WriteFile(hFile,
    pFileContent,
    ,
    &dwReaded,
    &o_Write);
    DWORD dwError = ::GetLastError();
    if(!bReadDone && (dwError == ERROR_IO_PENDING))
    {
    WaitForSingleObject(o_Write.hEvent,INFINITE);
    bReadDone = TRUE;
    } if(bReadDone)
    wcout<<L"I/O Code:"<<o_Write.Internal<<" TransedBytes:"<<o_Write.InternalHigh<<endl;
    else
    wcout<<"Error:"<<::GetLastError()<<endl;
    ::CloseHandle(hFile);
    delete [] pFileContent;
    }
  3. 可提醒IO
    void Test3()
    {
    //可提醒IO
    HANDLE hFile = ::CreateFile(_T("aaa.txt"),
    GENERIC_WRITE,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,
    NULL);
    if(!hFile)
    {
    wcout<<L"CreateFile Failed ErroCode:"<<::GetLastError()<<endl;
    return ;
    }
    DWORD dwFileSize = ::GetFileSize(hFile,);
    wcout<<L"FileSize:"<<dwFileSize<<endl;
    LARGE_INTEGER liDis = {};
    LARGE_INTEGER liRet = {};
    ::SetFilePointerEx(hFile,liDis,&liRet,FILE_END);
    wcout<<L"PreWrite File Pos:"<<liRet.LowPart<<endl;
    char * pFileContent = new char[];
    memset(pFileContent,'g',);
    DWORD dwReaded = ;
    OVERLAPPED o_Write = {};
    o_Write.Offset = liRet.LowPart;
    DWORD bReadDone = ::WriteFileEx(hFile,
    pFileContent,
    ,
    &o_Write,
    FileIOCompletionRoutine); ::CloseHandle(hFile);
    SleepEx(,TRUE);
    delete [] pFileContent;
    }

    可提醒IO的优劣:

    (1)由于回调函数的原因,最终不得不把大量信息放在全局变量中。使代码变的更加复杂

    (2)发出请求线程和完成处理必须是同一线程,没有达到线程负载均衡

    可提醒IO相关函数

    (1)QueueUserAPC函数

    a.这个函数允许我们手动增加APC项。

    b.可以强制线程退出等待状态比如WaitForSingleObjectEx 以下是示例代码

    
    
    VOID WINAPI APCFunc(ULONG_PTR pvParam)
    {
    //Nothing To Do
    } UINT WINAPI ThreadFunc(PVOID pvParam)
    {
    wcout<<L"start Wait...."<<endl;
    DWORD dw = ::WaitForSingleObjectEx(pvParam,INFINITE,TRUE);
    if(dw == WAIT_OBJECT_0)
    {
    wcout<<L"Event signaled"<<endl;
    return ;
    }
    else if(dw == WAIT_IO_COMPLETION)
    {
    wcout<<L"QueueUserApc Forced us out of a wait state"<<endl;
    return ;
    }
    return ;
    }
    void Test4()
    {
    //利用QueueUserApc来停止线程等待
    HANDLE hEvent = ::CreateEvent(NULL,FALSE,FALSE,NULL);
    HANDLE hThread = (HANDLE) _beginthreadex(NULL,,ThreadFunc,hEvent,,NULL);
    Sleep();
    QueueUserAPC(APCFunc,hThread,NULL);
    WaitForSingleObject(hThread,INFINITE);
    CloseHandle(hThread);
    CloseHandle(hEvent);
    }
    
    
    
    
  4. I/O完成端口
    待续
    void Test5()
    {
    //I/O完成端口
    TCHAR SrcFileName[MAXSIZE];
    TCHAR DesFileName[MAXSIZE]; cout<<"请输入源文件名:\n";
    wcin>>SrcFileName; cout<<"请输入目的文件名:\n";
    wcin>>DesFileName; HANDLE hSrcFile=CreateFile(SrcFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_FLAG_OVERLAPPED,NULL);
    if(hSrcFile==INVALID_HANDLE_VALUE)
    {
    printf("文件打开失败!");
    }
    DWORD FileSizeHigh;
    DWORD FileSize=GetFileSize(hSrcFile,&FileSizeHigh); HANDLE hDstFile=CreateFile(DesFileName,GENERIC_WRITE,,NULL,CREATE_NEW,FILE_FLAG_OVERLAPPED,NULL); //创建完成端口
    HANDLE hIOCP=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,,);
    if(hIOCP==NULL)
    {
    printf("完成端口创建失败!");
    } //绑定完成端口
    CreateIoCompletionPort(hSrcFile,hIOCP,READ_KEY,);
    CreateIoCompletionPort(hDstFile,hIOCP,WRITE_KEY,); OVERLAPPED ov={};
    PostQueuedCompletionStatus(hIOCP,,WRITE_KEY,&ov);
    OVERLAPPED ovSrc={};
    OVERLAPPED ovDes={};
    ULONG_PTR CompletionKey;
    BYTE* pBuffer=new BYTE[BUFFERSIZE];
    int i=;
    int j=;
    while(true)
    {
    DWORD nTransfer;
    OVERLAPPED* o; GetQueuedCompletionStatus(hIOCP,&nTransfer,&CompletionKey,&o,INFINITE);
    switch(CompletionKey)
    {
    case READ_KEY:
    //代表读取IO操作已经完成,进行下一步写入操作
    WriteFile(hDstFile,pBuffer,o->InternalHigh,NULL,&ovDes);
    cout<<"write:"<<++i<<endl;
    ovDes.Offset+=o->InternalHigh;
    //if(ovDes.Offset== FileSize/1024 )
    // return 0;
    break;
    case WRITE_KEY:
    //代表写入IO操作已经完成,进行下一步读取操作
    memset(pBuffer,,BUFFERSIZE*sizeof(BYTE));
    if(ovSrc.Offset < FileSize)//文件读取未完成
    {
    DWORD nBytes;
    if(ovSrc.Offset+BUFFERSIZE < FileSize)
    nBytes=BUFFERSIZE;
    else
    nBytes=FileSize-ovSrc.Offset;
    ReadFile(hSrcFile,pBuffer,nBytes,NULL,&ovSrc);
    cout<<"read:"<<++j<<endl; ovSrc.Offset+=nBytes;
    }
    else
    return ;
    break;
    default:
    break; }
    } return ;
    }

最新文章

  1. C#网络编程基础知识
  2. 王高利:Linux__apache,安装,报错解决
  3. css整理-03 文本
  4. Connection Management and Security
  5. CSS Hack技术(一)
  6. JavaScript语言常量和变量
  7. 中文翻译:pjsip教程(二)之ICE穿越打洞:Interactive Connectivity Establishment简介
  8. VS2008常见编译错误(总结篇)
  9. uncompyle2 windows安装和使用方法
  10. Windows下使用notepad++对文本进行行列转换
  11. springMVC源码解析--HandlerMethodArgumentResolverComposite参数解析器集合(二)
  12. Nginx代理实现内网主机访问公网服务
  13. iptables 扩展匹配 第三章
  14. MT【64】2017联赛一试不等式的一个加强练习
  15. NutzWk 开发框架
  16. 如何设置Java虚拟机JVM启动内存参数
  17. linux学习笔记-2.常用命令
  18. 添加用户username到sudo组
  19. 在实际项目开发中keil的调试方法
  20. 这可能是最详细的 iOS 学习入门指南(含书目/文档/学习资料)

热门文章

  1. 夺命雷公狗---微信开发52----网页授权(oauth2.0)获取用户基本信息接口(2)
  2. 9. 星际争霸之php设计模式--代理模式
  3. InstallShield 下载安装
  4. 常用的网络配置命令 ifconfig 所在的包
  5. Spring之AOP面向切片
  6. 查看linux僵尸进程
  7. JVM学习笔记(二)------Java代码编译和执行的整个过程【转】
  8. Java中IO流中所涉及到的各类方法介绍
  9. java.security.NoSuchAlgorithmException: DES KeyGenerator not available
  10. PHP中使用数组指针函数操作数组示例