[IO复用] Windows IOCP的初步学习

2024-02-22 07:20

本文主要是介绍[IO复用] Windows IOCP的初步学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 正文
    • 重叠 IO
      • 如何理解重叠IO:
      • 创建重叠IO
      • 重叠IO操作的返回值
      • 如何确认IO操作的结果
    • IOCP比重叠IO多了什么
    • IOCP的流程
    • IOCP和EPOLL的比较
  • 参考

前言

提起IO复用,大部分人首先接触的都是Select、Poll、Epoll,但是在不同的系统中,
往往有不同的高性能IO复用模型,比如Windows中就提供了IOCP(I/O Completion Port/完成端口)。

IOCP是一个异步的IO复用模型,应用程序只需要把IO请求投递给内核,具体的操作会由内核来执行,应用程序只需要获取执行结果就行了 。这一点上来看,性能是非常好的。

我在学习IOCP,这篇文章用于整理搜集到的资料,便于对IOCP进行理解。
这里没有实现任何我自己的代码,以后会参考Windows Socket五种I/O模型来实现代码。

正文

重叠 IO

IOCP是基于重叠IO来实现的。所以学习IOCP,必须先了解重叠IO。

如何理解重叠IO:

同一线程内部向多个目标传输(或从多个目标接收)数据引起的I/O重叠现象称为“重叠I/O”。为了完成这项任务,调用的I/O函数应立即返回,因此前提条件是异步I/O
而且,为了完成异步I/O,调用的I/O函数应以非阻塞模式工作
Windows中重叠I/O的重点并非I/O本身,而是如何确认I/O完成时的状态
————————————————
网络编程-重叠I/O模型

我们socket的操作本质上都是字符串的拷贝复制,重叠IO是windows提供的一种异步读写文件的机制,将读的指令以及我们的buffer投给操作系统,然后函数直接返回,操作系统独立开个线程,将数据复制进咱们的buffer,数据复制期间,我们就可以去做其他事,即读写过程变成了异步,可以同时投递多个读写操作。
————————————————
windows socket网络编程五:重叠IO模型

创建重叠IO

首先创建支持重叠IO的socket,需要把WSASocket()的最后一个参数dwFlags,设置为WSA_FLAG_OVERLAPPED。

WSASocket(PF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);

如果想要对Socket进行异步操作,需要地道用WSAAccept、WSASend等WSA函数。

重叠IO操作的返回值

当我们对一个重叠IO进行read/write/send/recv时,返回值是ERROR_IO_PENDING时,不是发生了错误,而是系统接收了这个IO操作的投递,过一段时间系统才会结束IO操作。

如何确认IO操作的结果

有两种方式:

  1. 等候事件
    我们在进行重叠IO的异步操作时,需要指定一个WSAOVERLAPPED对象。例如:
	evObj = WSACreateEvent();memset(&overlapped, 0, sizeof(overlapped));overlapped.hEvent = evObj;dataBuf.len = strlen(msg) + 1;dataBuf.buf = msg;if (WSASend(hSocket, &dataBuf, 1, &sendBytes, 0, &overlapped, NULL) == SOCKET_ERROR){if (WSAGetLastError() == WSA_IO_PENDING){puts("Background data send");WSAWaitForMultipleEvents(1, &evObj, TRUE, WSA_INFINITE, FALSE);              // 完成I/O时,evObj将变为signaled,函数返回WSAGetOverlappedResult(hSocket, &overlapped, &sendBytes, FALSE, NULL);}else{ErrorHandling("WSASend() error");}}
———————————————                        
原文链接:https://blog.csdn.net/beilizhang/article/details/124586262

给overlapped.hEvent关联一个事件,然后等候事件有信号,再用WSAGetOverlappedResult()检查IO操作结果。

  1. 添加回调函数
    这种方式不必设置overlapped.hEvent,把他保持zeromemery状态就可以。
    当IO操作完成,会自动调用回调函数CompRoutine()。
	memset(&overlapped, 0, sizeof(overlapped));dataBuf.len = BUF_SIZE;dataBuf.buf = buf;evObj = WSACreateEvent();if (WSARecv(hRecvSock, &dataBuf, 1, &recvBytes, &flags, &overlapped, CompRoutine) == SOCKET_ERROR) // 必须指定第六个参数WSAOVERLAPPED结构体变量的地址值,但不必为了hEvent成员创建事件对象{if (WSAGetLastError() == WSA_IO_PENDING){puts("Background data receive");}}————————————————                 
原文链接:https://blog.csdn.net/beilizhang/article/details/124586262

IOCP比重叠IO多了什么

  1. IOCP比重叠端口,多了一个投递队列,应用程序把要进行的IO操作,添加到队列中。
    然后通过一个GetQueuedCompletionStatus()接口,来获取投递的IO操作的结果。
  2. IOCP可以指定最多使用多少线程,来执行异步的IO操作。

1 完成端口IOCP模型
一个完成端口实际上就是一个通知队列,操作系统把已经完成的重叠I/0请求的通知放到队列中。完成端口会充分利用Windows最复杂的内核对象来进行I/O的调度,属于异步IO,是用于C/S通信模式中性能最好的网络通信模型。
2.完成端口IOCP模型的原理
完成端口创建几个线程(系统CPU的数目、避免线程上下文切换),等到用户请求的时候,就把这些请求都加入到一个公共消息队列中去,然后这几个线程就排队从消息队列中取出消息并加以处理,这种方式就很优雅的实现了异步通信和负载均衡的问题,因为它提供了一种机制来使用几个线程“公平的“处理来自于多个客户端的输入/输出,并且线程如果没事干的时候也会被系统挂起,不会占用CPU周期,这个关键的作为交换的消息队列,就是完成端口。
————————————————
O模型之完成端口completion port(windows上性能最好)

IOCP的流程

以下四个步骤来自于:Windows 下 IOCP 的简单使用,其中有各个步骤的示例代码。

  • 初始化 Socket 和 IOCP
    这里初始化的是用于listen的socket,需要对socket进行bind() 和listen()

  • 启动 Accpet 处理线程
    这里的Accept没有投递给IOCP来处理,而是在线程中,调用Accept()来接收连接,然后再把连接socket绑定到IOCP HANDLE上。
    创建IOCP和把socket绑定到IOCP HANDLE上,都是用CreateIoCompletionPort(),只是参数不同。

  • 启动 Event 处理线程
    事件处理的线程中,需要不断调用GetQueuedCompletionStatus()来获取IO的处理结果。
    没有收到结果是,GetQueuedCompletionStatus()会阻塞。

    这个API的第2个参数,lpNumberOfBytesTransferred,是在完成的 I/O 操作中传输的字节数,
    当它为-1时,代表收到 PostQueuedCompletionStatus() 发出的退出指令。

  • 设计一个靠谱的线程退出方式
    通过收到 PostQueuedCompletionStatus(),第2个参数设置为-1,来发出的退出指令。

IOCP和EPOLL的比较

  • Epoll 是Linux系统下的模型;IOCP 是Windows下模型;
  • Epoll 是同步模型(也看到有人说是异步的),在有事件时触发时,返回可处理的消息,由应用程序进行处理。IOCP是异步模型,处理完IO事件后,返回结果通知。

参考

Windows Socket五种I/O模型
I/O 完成端口-learn.microsoft
Windows 下 IOCP 的简单使用
技术派-epoll和IOCP之比较
网络编程-重叠I/O模型
揭开重叠IO的神秘面纱
windows socket网络编程五:重叠IO模型
windows socket网络编程六:完成端口模型
Windows下IOCP踩过的一些坑
O模型之完成端口completion port(windows上性能最好)

这篇关于[IO复用] Windows IOCP的初步学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/734509

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件