【免杀前置课——Windows编程】十四、异步IO——什么是异步IO、API定位问题、APC调用队列

news2024/11/16 19:26:18

异步IO

  • 异步IO
    • 异步I/0注意事项:
  • 定位问题
    • 总解决方案
      • APC调用队列

异步IO

当我们读取一个文件时,一般情况下,线程是阻塞的,也就是说,当前线程在等待文件读取操作结束,这种方式叫同步IO
Windows 在系统底层为用户实现了另外一种高效的机制,叫重叠I/0,又称作异步I/0。异步I/0提供了这样一种功能,当用户读取文件的时候,读取文件函数会立马返回结果不会阻塞线程,但是实际上文件并没有读取完,而是交给了系统底层自动去处理,这样文件的读取操作就不会阻塞住你的线程。但是这种引发了一个问题,我们如何才能知道文件已经读取完毕了呢? I

异步I/0注意事项:

一旦一个句柄是以异步I/0的方式打开的,那么:
1、句柄变为可等待的对象,就是说,它具有了激发态和非激发态。
2、文件指针这个东西就失效了,需要用overlapped结构体中的offset表示读取或写入的位置。

在这里插入图片描述
在这里插入图片描述

定位问题

异步IO存在问题,如果不止通过一个句柄进行读操作还有其他操作,则GetOverlappedResult函数无法定位到是哪一个操作。

#include<iostream>
#include<Windows.h>

int main() 
{
	//用异步IO方式打开一个文件
	HANDLE hFile = CreateFileW(L"D:\\code\\VisualStudio2022\\异步Io\\异步Io\\test.txt", GENERIC_ALL, NULL, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);//FILE_FLAG_OVERLAPPED异步IO
	CHAR buff[0X100]{ 0 };
	OVERLAPPED overlapped{ 0 };
	//读取文件内容
	ReadFile(hFile, buff, 0X100, NULL, &overlapped);
	DWORD numberOfBytes = 0;
	WaitForSingleObject(hFile, -1);
	GetOverlappedResult(hFile, &overlapped, &numberOfBytes, FALSE);
	printf("文件内容:%s\n", buff);
	printf("实际完成IO数:%d\n", numberOfBytes);
	CloseHandle(hFile);
	return 0;
}

在这里插入图片描述
解决无法精确定位是哪个API完成的问题。新问题是,到最后还是要调用WaitForSingleObject函数,如果操作过大还是会导致卡顿,无法流畅体验。

#include<iostream>
#include<Windows.h>

int main()
{
	HANDLE hFile = CreateFile(L"D:\\code\\VisualStudio2022\\异步Io\\异步Io\\test.txt", GENERIC_ALL, NULL, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	OVERLAPPED overlapped{ 0 };
	OVERLAPPED overlapped1{ 0 };
	overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	overlapped1.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	char buff[0X100]{ 0 };
	char buff1[0X100]{ 0 };
	ReadFile(hFile, buff, 10, NULL, &overlapped);
	ReadFile(hFile, buff1, 20, NULL, &overlapped1);
	//精确地判断哪个结束
	WaitForSingleObject(overlapped.hEvent, -1);
	WaitForSingleObject(overlapped1.hEvent, -1);
	printf("%s\n", buff);
	printf("%s\n", buff1);

	return 0;
}

总解决方案

APC调用队列

每个线程都维护了一个APC(异步过程调用)队列,队列中的每一项都是函数,当一个线程处于可警醒(闲暇)状态时,线程会遍历自己的APC队列并调用所有的函数,直到结束,再恢复执行。
每当有一个异步IO请求完成的时候,ReadFileEx,就会像APC队列中添加相应的函数和对应的参数,添加的顺序和投递的顺序不一定相同,哪个先处理完就先投递哪个。

通过ReadFileEx函数,让每一个异步IO完成后都向APC队列中加入函数及相应参数,来判断线程顺序的同时不使用WaitForSingleObject等待激发且抢占不影响流畅性。

#include<iostream>
#include<Windows.h>

void WINAPI overLappedCompletionProc(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
{
	if (lpOverlapped->hEvent == (HANDLE)0X100)
	{
		printf("1完成了\n");
	}
	else {
		printf("2完成了\n");
	}
}

int main()
{
	HANDLE hFile = CreateFile(L"D:\\code\\VisualStudio2022\\异步Io\\异步Io\\test.txt", GENERIC_ALL, NULL, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	OVERLAPPED overlapped{ 0 };
	OVERLAPPED overlapped1{ 0 };
	//overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	//overlapped1.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	overlapped.hEvent = (HANDLE)0X100;
	overlapped1.hEvent = (HANDLE)0X200;
	char buff[0X100]{ 0 };
	char buff1[0X100]{ 0 };
	//当有一个异步IO请求完成后,就会向APC队列中添加相应的函数和对应的参数
	ReadFileEx(hFile, buff, 10, &overlapped, overLappedCompletionProc);
	ReadFileEx(hFile, buff1, 20, &overlapped1, overLappedCompletionProc);//当进程处于激发态时触发,通过Sleep让进程处于激发态
	SleepEx(0, TRUE);
	//ReadFile(hFile, buff, 10, NULL, &overlapped);
	//ReadFile(hFile, buff1, 20, NULL, &overlapped1);
	//精确地判断哪个结束
	//WaitForSingleObject(overlapped.hEvent, -1);
	//WaitForSingleObject(overlapped1.hEvent, -1);
	printf("%s\n", buff);
	printf("%s\n", buff1);

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/63772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【软考】-- 操作系统(下)

操作系统&#xff08;下&#xff09;第五节 文件管理&#x1f355;一、文件管理的基本概念1️⃣文件2️⃣文件目录3️⃣目录结构:&#x1f354;二、文件路径&#x1f35f;三、文件命名规则&#x1f32d;四、文件的基本操作&#x1f37f;五、文件类型与扩展名&#x1f9c2;六、系…

Docker中安装Kibana

Kibana是一个免费且开放的用户界面,能够让你对Elasticsearch 数据进行可视化,并让你在Elastic Stack中进行导航。你可以进行各种操作,从跟踪查询负载,到理解请求如何流经你的整个应用,都能轻松完成。 在Docker Hub中选择最新版本的Kibaba镜像(选择版本为8.5.1),如下图…

bigquant选股模型主要有哪些?

bigquant选股模型一般常见的有七种&#xff0c;即多因子模型、风格轮动模型、行业轮动模型、资金流模型、动量反转模型、一致预期模型、趋势追踪模型等方面。不过要想样样都学会精通也是需要花费时间&#xff0c;以及精力等&#xff0c;那么&#xff0c;小编就从最基本的多因子…

DPDK Mempool

mempool是DPDK提供的内存池&#xff0c;其用处有&#xff1a; 由于DPDK使用UIO让DMA将网卡中的数据直接拷贝至用户态&#xff0c;因此需要一块固定的区域提供给DMA重复利用内存&#xff0c;提高效率 结构 mempool的主要结构如下图所示。 mempool为每个注册的lcore都分配了一…

Node.js - nvm管理node.js版本

使用nvm来管理node.js的版本真的很方便&#xff0c;这样就可以根据自己的需要来回切换node.js版本&#xff01; 一、卸载本地安装的node.js版本 略 二、安装nvm管理工具 2.1、下载 https://github.com/coreybutler/nvm-windows/releases 2.2 安装 (1) 鼠标双击nvm-setup.exe文件…

【从零开始学习深度学习】7.自己动手实现softmax回归的训练与预测

基于上一篇文章读取fashion-minist数据集的基础&#xff0c;本文自己动手实现一个softmax模型对其进行训练与预测。 目录1. 自己动手实现softmax回归1.1 读取数据1.2 初始化模型参数1.3 实现softmax运算1.4 定义模型1.5 定义损失函数1.6 计算分类准确率1.7 训练模型1.8 预测完整…

面试碰壁15次!作为一个已经27岁的测试工程师,未来在何方....

3年测试经验原来什么都不是&#xff0c;只是给你的简历上画了一笔&#xff0c;一直觉得经验多&#xff0c;无论在哪都能找到满意的工作&#xff0c;但是现实却是给我打了一个大巴掌&#xff01;事后也不会给糖的那种... 先说一下自己的个人情况&#xff0c;普通二本计算机专业…

LabVIEW编程LabVIEW开发SMP10辐射表例程与相关资料

LabVIEW编程LabVIEW开发SMP10辐射表例程与相关资料 ​​SMP10辐射表是荷兰Kipp&Zonen公司的一种用于测量短波辐射的产品&#xff0c;配有只能型接口&#xff0c;能够提供标准输出&#xff0c;能耗低。 作为一款副基准总辐射表,SMP10结合了CMP 11的传感器技术、SMP 11的智…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java基于自组网的空地一体化信息系统mf392

面对老师五花八门的设计要求&#xff0c;首先自己要明确好自己的题目方向&#xff0c;并且与老师多多沟通&#xff0c;用什么编程语言&#xff0c;使用到什么数据库&#xff0c;确定好了&#xff0c;在开始着手毕业设计。 1&#xff1a;选择课题的第一选择就是尽量选择指导老师…

[附源码]计算机毕业设计JAVA疫情期间回乡人员管理系统

[附源码]计算机毕业设计JAVA疫情期间回乡人员管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM…

基于Java的课程管理系统

摘 要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括课程管理系统的网络应用&#xff0c;在外国课程管理已经是很普遍的方式&#xff0c;不过国内的课程管理可能还处于起步阶段。课程管理系统具有下载课件功能。课程管理系…

数据结构(12)Dijkstra算法JAVA版:图的最短路径问题

目录 12.1.概述 12.1.1.无权图的最短路径 12.1.2.带权图的最短路径 1.单源最短路径 2.多源最短路径 12.2.代码实现 12.1.概述 12.1.1.无权图的最短路径 无权图的最短路径&#xff0c;即最少步数&#xff0c;使用BFS贪心算法来求解最短路径&#xff0c;比较好实现&#xf…

04-05 - 主引导程序的扩展(实验未完)

---- 整理自狄泰软件唐佐林老师课程 1. 突破限制的思路 限制&#xff1a;主引导程序的代码不能超过512字节 主引导程序完成&#xff1a; 完成最基本的初始化工作从存储介质中加载程序到内存将控制权交由新加载的程序执行…… 问题&#xff1a; 主引导程序如何加载存储介质中的…

Windows上Qt源码调试(使用VS2017调试qt5.12.0)

环境&#xff1a;vs2017 qt 5.12.0 msvc32和msvc64 1.下载源代码 把所用 Qt 库版本对应源码&#xff08;qt-everywhere-src-5.12.0&#xff09;下载来解压&#xff08;https://download.qt.io/archive/qt/5.12/5.12.0/single/&#xff09;&#xff0c;或者安装时选择把源码&…

一文带你掌握JSP基础知识

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;JAVA开发者…

赋能建筑建材企业物流网络内外联通,B2B交易管理系统打造行业智慧供应链

数据显示&#xff0c;在疫情和行业转型升级的双重压力下&#xff0c;行业中竞争力不强、商业模式老套的建筑建材企业在疫情中产值下降甚至被淘汰出局。随着数字经济的兴起&#xff0c;传统建筑建材产业的发展也带来了巨大的变革。 据有关数据分析指出&#xff0c;数字化已经成…

数据之道读书笔记-08打造“清洁数据”的质量综合管理能力

数据之道读书笔记-08打造“清洁数据”的质量综合管理能力 越来越多的企业应用和服务都基于数据而建&#xff0c;数据质量是数据价值得以发挥的前提。例如企业运营效率主要依赖于数据获取的准确性和及时性&#xff0c;企业客户关系管理系统中的错误或不完整数据将导致客户沟通不…

安卓讲课笔记6.1 共享参数

文章目录零、本讲学习目标一、导入新课二、新课讲解&#xff08;一&#xff09;数据存储&#xff08;二&#xff09;共享参数1、共享参数概述2、利用共享参数读写文件步骤&#xff08;三&#xff09;案例演示&#xff1a;多窗口共享数据1、创建安卓应用2、准备图片素材3、主界面…

【LeetCode每日一题】——141.环形链表

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【题目提示】八【题目进阶】九【时间频度】十【代码实现】十一【提交结果】一【题目类别】 链表 二【题目难度】 简单 三【题目编号】 141.环形链表 四【题目描述】 给…

【gbase8a】docker搭建gbase8a,详细【图文】

docker搭建gbase8a安装docker安装GBase 8a查询安装的版本拉取镜像启动进入容器创建用户dbever测试安装docker 其中具有docker的搭建 搭建docker&#xff0c;docker搭建达梦数据库&#xff0c;详细【图文】 https://blog.csdn.net/weixin_44385419/article/details/127738868 d…