Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Windows核心编程:第10章 同步设备IO与异步设备IO

Windows核心编程:第10章 同步设备IO与异步设备IO

作者头像
gongluck
发布于 2019-02-22 01:48:44
发布于 2019-02-22 01:48:44
84500
代码可运行
举报
文章被收录于专栏:C++C++
运行总次数:0
代码可运行

Github

https://github.com/gongluck/Windows-Core-Program.git

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//第10章 同步设备IO与异步设备IO.cpp: 定义应用程序的入口点。
//

#include "stdafx.h"
#include "第10章 同步设备IO与异步设备IO.h"

//可提醒IO回调
VOID WINAPI funComplete(
    _In_    DWORD dwErrorCode,
    _In_    DWORD dwNumberOfBytesTransfered,
    _Inout_ LPOVERLAPPED lpOverlapped
)
{

}

//IO完成端口工作线程
DWORD WINAPI workthread(LPVOID lpThreadParameter)
{
    DWORD NumberOfBytesTransferred;
    DWORD CompletionKey;
    OVERLAPPED* pOverlapped;
    BOOL bres = GetQueuedCompletionStatus(lpThreadParameter, &NumberOfBytesTransferred, &CompletionKey, &pOverlapped, INFINITE);
    //GetQueuedCompletionStatusEx可获取多个IO请求结果
    DWORD dres = GetLastError();

    return 0;
}

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    //打开(创建)文件
    HANDLE hFile = CreateFile(TEXT("第10章 同步设备IO与异步设备IO.cpp"), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        MessageBox(nullptr, TEXT("打开文件失败!"), TEXT("error"), MB_OK);
        return 0;
    }

    //文件类型
    DWORD dres = GetFileType(hFile);
    //dres == FILE_TYPE_DISK

    //文件大小
    LARGE_INTEGER li;
    BOOL bres = GetFileSizeEx(hFile, &li);//逻辑大小
    li.LowPart = GetCompressedFileSize(TEXT("第10章 同步设备IO与异步设备IO.cpp"), (DWORD*)&li.HighPart);//物理大小

    //文件指针
    li.QuadPart = 0;
    bres = SetFilePointerEx(hFile, li, nullptr, FILE_END);
    bres = SetFilePointerEx(hFile, li, &li, FILE_CURRENT);
    bres = SetEndOfFile(hFile);
    li.QuadPart = 0;
    bres = SetFilePointerEx(hFile, li, nullptr, FILE_BEGIN);

    //同步IO
    char* buf = new char[100];
    bres = ReadFile(hFile, buf, 100, &dres, nullptr);
    delete []buf;
    buf = nullptr;

    //刷新缓冲区
    bres = FlushFileBuffers(hFile);

    //CancelSynchronousIo
    //取消线程未完成的同步IO请求

    //关闭文件
    CloseHandle(hFile);
    hFile = nullptr;

    //异步IO
    HANDLE hFile2 = CreateFile(TEXT("第10章 同步设备IO与异步设备IO.cpp"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);
    OVERLAPPED ol;
    ol.Offset = 1024;
    ol.OffsetHigh = 0;
    ol.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
    char* buf2 = new char[1024];
    bres = ReadFile(hFile2, buf2, 1024, nullptr, &ol);//异步方式总是返回FALSE
    dres = GetLastError();
    switch (dres)
    {
    case ERROR_IO_PENDING:
        //IO请求添加成功
        //WaitForSingleObject(hFile2, INFINITE);
        WaitForSingleObject(ol.hEvent, INFINITE);
        break;
    case ERROR_INVALID_USER_BUFFER:
    case ERROR_NOT_ENOUGH_MEMORY:
        break;
    case ERROR_NOT_ENOUGH_QUOTA:
        break;
    default:
        break;
    }

    //取消队列中的IO请求
    //bres = CancelIo(hFile2);
    bres = CancelIoEx(hFile2, &ol);
    //bres = CancelIoEx(hFile2, nullptr);
    //bres = CloseHandle(hFile2);

    if (ol.hEvent != nullptr)
    {
        CloseHandle(ol.hEvent);
        ol.hEvent = nullptr;
    }

    //可提醒IO
    OVERLAPPED ol2;
    ol2.Offset = 1024;
    ol2.OffsetHigh = 0;
    ol2.hEvent = nullptr;
    dres = ReadFileEx(hFile2, buf2, 1024, &ol2, funComplete);//回调函数在同一个线程空间
    //置为可提醒状态
    //APC队列中只要有一个,线程就不会进入睡眠
    dres = SleepEx(INFINITE, TRUE);
    //WaitForSingleObjectEx
    //WaitForMultipleObjectsEx
    //SignalObjectAndWait
    //GetQueuedCompletionStatusEx
    //MsgWaitForMultipleObjectsEx
    dres = GetLastError();//WAIT_IO_COMPLETION

    //手动添加一项到APC队列
    //可以让目标线程结束睡眠
    dres = QueueUserAPC((PAPCFUNC)funComplete, GetCurrentThread(), NULL);

    //IO完成端口
    HANDLE iocp = CreateIoCompletionPort(hFile2, nullptr, 1, 2);
    HANDLE hts[2];
    for (int i = 0; i < 2; ++i)
        hts[i] = CreateThread(nullptr, 0, workthread, iocp, 0, nullptr);
    bres = PostQueuedCompletionStatus(iocp, 100, 1, &ol); //模拟发送IO请求完成
    bres = ReadFile(hFile2, buf2, 1024, nullptr, &ol2);
    dres = GetLastError();

    WaitForMultipleObjects(2, hts, TRUE, INFINITE);
    for (int i = 0; i < 2; ++i)
    {
        CloseHandle(hts[i]);
        hts[i] = nullptr;
    }
    CloseHandle(iocp);
    iocp = nullptr;

    CloseHandle(hFile2);
    hFile2 = nullptr;
    delete[]buf2;
    buf2 = nullptr;

    system("pause");
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-07-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Windows核心编程:第11章 Windows线程池
https://github.com/gongluck/Windows-Core-Program.git
gongluck
2019/02/22
1.2K0
Windows核心编程:第9章 用内核对象进行线程同步
https://github.com/gongluck/Windows-Core-Program.git
gongluck
2019/02/22
8340
windows 下文件的高级操作
本文主要说明在Windows下操作文件的高级方法,比如直接读写磁盘,文件的异步操作,而文件普通的读写方式在网上可以找到一大堆资料,在这也就不再进行专门的说明。
Masimaro
2018/08/31
2.2K0
Windows核心编程:第7章 线程调度、优先级和关联性
Github https://github.com/gongluck/Windows-Core-Program.git //第7章 线程调度、优先级和关联性.cpp: 定义应用程序的入口点。 // #include "stdafx.h" #include "第7章 线程调度、优先级和关联性.h" //线程函数 DWORD WINAPI ThreadProc(PVOID param) { return 0; } int APIENTRY wWinMain(_In_ HINSTANCE hInst
gongluck
2018/06/22
1.1K0
Windows核心编程:第4章 进程
Github https://github.com/gongluck/Windows-Core-Program.git //第4章 进程.cpp: 定义应用程序的入口点。 // #include "stdafx.h" #include "第4章 进程.h" #include <shellapi.h> #pragma warning(disable:4996)//GetVersionEx int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
gongluck
2018/06/22
6220
Windows核心编程:第8章 用户模式下的线程同步
https://github.com/gongluck/Windows-Core-Program.git
gongluck
2019/02/22
5480
Windows核心编程:第6章 线程基础
Github https://github.com/gongluck/Windows-Core-Program.git //第6章 线程基础.cpp: 定义应用程序的入口点。 // #include "stdafx.h" #include "第6章 线程基础.h" #include <process.h> //线程函数 DWORD WINAPI ThreadProc(PVOID param) { return 0; } unsigned __stdcall ThreadProc2(void* p
gongluck
2018/06/22
4580
I/O接口_overlapping
Overlapped I/O是Windows系统上的Asynchronous I/O implementation。啥叫asynchronous I/O ?借用Linux Man page中对AIO的介绍:
全栈程序员站长
2022/09/20
4540
Windows核心编程:第3章 内核对象
Github https://github.com/gongluck/Windows-Core-Program.git //第3章 内核对象.cpp: 定义应用程序的入口点。 // #include "stdafx.h" #include "第3章 内核对象.h" int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
gongluck
2018/06/22
3390
C++20 新特性重塑模板编程范式
在 Windows 客户端开发中,模板编程长期面临着抽象能力与可维护性的博弈。传统的模板元编程(TMP)虽然能实现类型安全的系统抽象(如 COM 组件封装、DirectX 资源管理),但复杂的 SFINAE 技巧和冗长的编译错误信息让开发者望而生畏。C++20 的三大核心特性——Concepts、Ranges 和 Modules——为这一困境提供了系统性解决方案。本章将通过 Windows 开发中的典型场景,深度解析这些特性如何重构现代模板编程范式。
lealc
2025/02/13
2570
C++20 新特性重塑模板编程范式
Windows核心编程:第1章 错误处理
Github https://github.com/gongluck/Windows-Core-Program.git //第1章 错误处理.cpp: 定义应用程序的入口点。 // #include "stdafx.h" #include "第1章 错误处理.h" int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _
gongluck
2018/06/22
4050
Windows核心编程:第12章 纤程
https://github.com/gongluck/Windows-Core-Program.git
gongluck
2019/02/22
8280
老版VC++线程池
在一般的设计中,当需要一个线程时,就创建一个,但是当线程过多时可能会影响系统的整体效率,这个性能的下降主要体现在:当线程过多时在线程间来回切换需要花费时间,而频繁的创建和销毁线程也需要花费额外的机器指令,同时在某些时候极少数线程可能就可以处理大量,比如http服务器可能只需要几个线程就可以处理用户发出的http请求,毕竟相对于用户需要长时间来阅读网页来说,CPU只是找到对应位置的页面返回即可。在这种情况下为每个用户连接创建一个线程长时间等待再次处理用户请求肯定是不划算的。为了解决这种问题,提出了线程池的概念,线程池中保存一定数量的 线程,当需要时,由线程池中的某一个线程来调用对应的处理函数。通过控制线程数量从而减少了CPU的线程切换,而且用完的线程还到线程池而不是销毁,下一次再用时直接从池中取,在某种程度上减少了线程创建与销毁的消耗,从而提高效率 在Windows上,使用线程池十分简单,它将线程池做为一个整体,当需要使用池中的线程时,只需要定义对应的回调函数,然后调用API将回调函数进行提交,系统自带的线程池就会自动执行对应的回调函数。从而实现任务的执行,这种方式相对于传统的VC线程来说,程序员不再需要关注线程的创建与销毁,以及线程的调度问题,这些统一由系统完成,只需要将精力集中到逻辑处理的回调函数中来,这样将程序员从繁杂的线程控制中解放出来。同时Windows中线程池一般具有动态调整线程数量的自主行为,它会根据线程中执行任务的工作量来自动调整线程数,即不让大量线程处于闲置状态,也不会因为线程过少而有大量任务处于等待状态。 在windows上主要有四种线程池 1. 普通线程池 2. 同步对象等待线程池 3. 定时器回调线程池 4. 完成端口回调线程池
Masimaro
2018/08/31
1.5K0
Windows核心编程:第5章 作业
Github https://github.com/gongluck/Windows-Core-Program.git //第5章 作业.cpp: 定义应用程序的入口点。 // #include "stdafx.h" #include "第5章 作业.h" int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _
gongluck
2018/06/22
8890
Win10 串口通信 —— 同步异步
之前接到的一个小项目,好像不能算。win10下的串口通信,不需要界面,排除了Qt,MFC只剩C++ 底层了,调用WindowsApi来实现。翻了翻网上资料大致写出来了。
何其不顾四月天
2023/03/10
1.3K0
关于windows完成端口(IOCP)的一些理解(一)
系列目录 关于windows完成端口(IOCP)的一些理解(一) 关于windows完成端口(IOCP)的一些理解(二) 关于windows完成端口(IOCP)的一些理解(三) 关于windows完成端口(IOCP)的一些理解(四) 关于windows完成端口(IOCP)的一些理解(五) 关于windows完成端口(IOCP)的一些理解(六) 本人很多年前接触完成端口以来,期间学习和练习了很多次,本以为自己真正地理解了其原理,最近在看网狐的服务器端源码时又再一次拾起完成端口的知识,结果发现以前理解的其实很多
范蠡
2018/04/13
7.4K0
异步方式串口收发数据
在现代软件开发中,串口通信仍然是一个重要的领域,尤其是在嵌入式系统、工业控制和物联网设备中。Windows操作系统提供了一套完整的API来支持串口通信,包括同步和异步两种模式。本文将重点介绍如何在Windows平台上使用异步方式进行串口数据的收发。
Michel_Rolle
2024/10/11
2.5K0
c++ 网络编程(九)TCP/IP LINUX/windows--使用IOCP模型 多线程超详细教程 以及 多线程实现服务端
原文链接:https://www.cnblogs.com/DOMLX/p/9661012.html
徐飞机
2018/09/30
3.2K0
c++ 网络编程(九)TCP/IP LINUX/windows--使用IOCP模型      多线程超详细教程 以及 多线程实现服务端
【操作系统】Windows进程间的通信
进程通常上被定义为一个正在运行的程序的实例,是一个程序在其自身的地址空间中的一次执行活动,一个程序可以对应多个进程。
半生瓜的blog
2023/05/13
9440
【操作系统】Windows进程间的通信
IOCP反射服务器
这两天学习了一下IOCP网络模型。 主要参考了这两片文章:http://blog.csdn.net/neicole/article/details/7549497/和http://blog.csdn.net/piggyxp/article/details/6922277 IOCP是我见过的最复杂的网络模型了,在Windows里肯定就是boss了,而且一开始我感觉IOCP甚至比epoll还要复杂(其实epoll也不复杂,全部都不复杂,只是不懂的人觉得复杂~)。当仔细研究一下之后,觉得也就 也像我很纠结的公事
_gongluck
2018/03/08
8590
IOCP反射服务器
相关推荐
Windows核心编程:第11章 Windows线程池
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验