[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上性能最好)

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

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

相关文章

10个行锁、死锁案例⭐️24张加锁分析图彻底搞懂Innodb行锁加锁规则!

10个行锁、死锁案例⭐️24张加锁分析图🚀彻底搞懂Innodb行锁加锁规则! 上篇文章 我们描述原子性与隔离性的实现,其中描述读操作解决隔离性问题的方案时还遗留了一个问题:写操作是如何解决不同的隔离性问题? 本篇文章…

linux CentOs 安装docker 推荐生产环境使用

目录 1. 在CentOs上安装docker所需的系统环境 2. 卸载旧版本 2.1 查看是否已安装docker 2.2 卸载已安装的docker 3. 安装方式 3.1 使用rpm存储库安装(推荐使用该方法) 3.2 从包中安装 4. 开始docker 1. 在CentOs上安装docker所需的系统环境 需要以下CentOS版本之一的维…

数据结构-邻接链表

介绍 邻接矩阵是运用较多的一种储存图的方法,但如果一张网图边数较少,就会出现二维矩阵中大部分数据为0的情况,浪费储存空间 为了避免空间浪费,也可以采用数组与链表结合的方式来存储图 假设有这样一张图 我们可以先用一个数组…

C#中的Async的异常处理

在C#的代码编写中可以通过try/catch来捕获Exception。然而当调用Async方法时需要特别注意 private void Start() {try{TestVoid();}catch (Exception e){Debug.LogException(e);} }private async void TestVoid() {var t Task.Delay(1);await t;throw new Exception("Te…

测试环境搭建整套大数据系统(四:ubuntu22.4创建普通用户)

一:创建用户,修改密码,增加sudo权限。 useradd dolphinscheduler #输入密码 passwd dolphinscheduler # 配置 sudo 免密 sed -i $adolphinscheduler ALL(ALL) NOPASSWD: NOPASSWD: ALL /etc/sudoers sed -i s/Defaults requirett/#Defa…

实现一个python代码编辑器

代码编辑器采用了monacoEditor,一个现成的编辑器。网上有很多文档介绍和开源项目,但是怎么说呢,跟着做,可以实现一个网页编辑器,可以高亮python的语法,但是没有python的提示,找不到可以参考的&a…

ADO.NET和EF框架性能对比

ADO.NET和Entity Framework(EF)框架在性能上有一些不同。总体来说,ADO.NET通常比EF具有更高的性能,特别是在执行大量数据访问操作时。下面是一些关于它们性能差异的要点: 数据库操作方式: ADO.NET&#xf…

C++ 八数码问题理解 `IDA*` 算法原则:及时止损,缘尽即散

1.前言 八数码是典型的状态搜索案例。如字符串转换问题、密码锁问题都是状态搜索问题。 状态搜索问题指由一种状态转换到到最终状态,求解中间需要经过多少步转换,或者说最小需要转换多少步,或者说有多少种转换方案。本文和大家聊聊八数码问…

使用哈希函数删除哈希值相同的文件

哈希函数及哈希值的定义 哈希函数是一种将任意长度的输入数据映射为固定长度的输出数据的函数。它通过对输入数据执行一系列复杂的数学运算,将数据转换为固定长度的唯一标识,这个唯一标识就是哈希值。 哈希函数的作用 数据唯一性: 对于不同的输入数据&…

Java面试题:volatile专题

王有志,一个分享硬核Java技术的互金摸鱼侠 加入Java人的提桶跑路群:共同富裕的Java人 今天是《面霸的自我修养》第4篇文章,我们一起来看看面试中会问到哪些关于volatile的问题吧。数据来源: 大部分来自于各机构(Java之父,Java继父,某灵,某泡,某客)以及各博主整理文档…

Java程序中为什么要使用StringBuilder

遇到这个问题是来源于leetcode的一道题&#xff1a;字符串解码。其中的题解涉及字符串的操作使用的是StringBuilder&#xff0c;不是String。 class Solution {public String decodeString(String s) {StringBuilder res new StringBuilder();int multi 0;LinkedList<Int…

MR专题:体验Apple Vision Pro多元生态内容,拥抱MR供应链机遇

今天分享的是MR系列深度研究报告&#xff1a;《MR专题&#xff1a;体验Apple Vision Pro多元生态内容&#xff0c;拥抱MR供应链机遇》。 &#xff08;报告出品方&#xff1a;方正证券&#xff09; 报告共计&#xff1a;15页 来源&#xff1a;人工智能学派 Apple Vision Pro…

基因富集分析——GO/DO

DO&#xff08;Disease Ontology&#xff09;分析涉及多种具体的步骤和方法&#xff0c;下面是一些常见的DO分析步骤或方法&#xff1a; 1. 疾病分类和定义&#xff1a;分析DO中的疾病分类体系&#xff0c;理解不同疾病之间的关系和归类。这包括查看DO本体中的层次结构、疾病之…

本地TCP通讯(C++)

概要 利用TCP技术&#xff0c;实现本地ROS1和ROS2的通讯。 服务端代码 头文件 #include <ros/ros.h> #include "std_msgs/String.h" #include "std_msgs/Bool.h" #include <iostream> #include <cstring> #include <unistd.h>…

消息队列-RabbitMQ:workQueues—工作队列、消息应答机制、RabbitMQ 持久化、不公平分发(能者多劳)

4、Work Queues Work Queues— 工作队列 (又称任务队列) 的主要思想是避免立即执行资源密集型任务&#xff0c;而不得不等待它完成。我们把任务封装为消息并将其发送到队列&#xff0c;在后台运行的工作进程将弹出任务并最终执行作业。当有多个工作线程时&#xff0c;这些工作…

AVEC-为编译后的可执行程序添加资源

AVEvasionCraftOnline 一个在线免杀的web端程序&#xff0c;可以绕过常见杀软 项目地址&#xff1a;https://github.com/yutianqaq/AVEvasionCraftOnline AVEvasionCraftOnline - 小更新 sha256sum AVEvasionCraftOnline.jar AVEvasionCraftOnline-v1.1.zip 896387a21946b1…

vulnhub练习 DC-1复现及分析

一、搭建环境 1.工具 靶机&#xff1a;DC-1 192.168.200.17 攻击机&#xff1a;kali 192.168.200.13 2.注意 攻击机和靶机的网络连接方式要相同&#xff0c;另外DC-1的网络连接方式我这里采用NAT模式&#xff0c;是与kali的网络连接模式相同的&#xff08;当然亦可以选用桥…

前端使用QGIS工具生成地图

1 找到所需要地图的 json 数据 1.1 查找 json 数据的两个网址&#xff08;个人常用&#xff09; 1.1.1 DataV.GeoAtlas 网站 DataV.GeoAtlas 这个网站不能具体到县内包含的城镇分化&#xff0c;但是对于县级以上的地图数据&#xff0c;使用起来很方便。 1.1.2 POI数据 网站 …

创作无版权素材:解放创意的利器

title: 创作无版权素材&#xff1a;解放创意的利器 date: 2024/2/21 13:52:09 updated: 2024/2/21 13:52:09 tags: 无版权创作自由法律合规节省成本提升质量多样素材创意工具 在当今数字化时代&#xff0c;内容创作成为了一种非常重要的方式来传达信息和表达创意。 然而&#…

【在 Windows 系统上开发 Flutter 项目并将其发布到 Ubuntu 服务器】

在 Windows 系统上开发 Flutter 项目并将其发布到 Ubuntu 服务器上&#xff0c;按照以下步骤进行操作&#xff1a; 构建 Flutter Web 应用&#xff1a; 在 Windows 系统上&#xff0c;进入Flutter 项目目录&#xff0c;然后运行 flutter build web 命令来构建你的 Flutter Web …