Linux网络编程:高级IO

news2024/11/22 18:39:22

目录

前言:

初识五种IO模型

初识高级IO

同步IO和异步IO

1.再谈五种IO模型

1.1.阻塞IO

1.2.非阻塞IO

1.3.信号驱动IO

1.4.IO多路复用

1.5.异步IO


前言:

在我们过去的学习中,我们对于IO的认识局限于input、output,也就是输入和输出,即对外设的访问,与计算机外部设备(如键盘、显示器、磁盘等)之间的数据交换。但是这在我们过去对IO接口的使用,例如:recv、send、write、scanf等函数时,我们能够感受到IO的本质就是在不同的缓冲区之间做数据的拷贝,并且在这个过程中会“等待”,比如recv函数需要数据写入到缓冲区中,scanf需要等待键盘写入……

IO的本质:等待数据的就绪 + 拷贝数据到相应的缓冲区。

初识五种IO模型

阻塞IO在阻塞IO模型中,当用户进程发起一个IO操作时,如果数据尚未准备好,用户进程将被阻塞,直到数据准备好后从内核空间复制到用户空间,IO操作才返回。
非阻塞IO非阻塞IO模型允许用户进程在发起IO操作后立即返回,而不会阻塞等待数据准备。然而,用户进程需要不断地轮询、重复请求来检查数据是否准备好。
IO多路复用IO多路复用模型通过引入select/poll/epoll等机制,允许用户进程同时监控多个文件描述符的状态变化,以决定哪些文件描述符可读、可写或有异常状态。
信号驱动IO信号驱动IO模型允许用户进程通过注册一个信号处理函数,当数据准备好时,由内核发送一个信号来通知用户进程进行IO操作。
异步IO异步IO模型允许用户进程发起一个IO操作后立即返回,并在数据准备好后由内核自动将数据从内核空间复制到用户空间,然后通知用户进程IO操作已完成。

我们在前言中知道了IO的本质就是等待数据、拷贝数据,我们也可以用生活中钓鱼的例子来抽象一下IO,也就是等待鱼上钩和钓鱼上来。那么以上的五种IO模型我们可以看成五个钓鱼佬,各自拥有着不同的钓鱼习惯!!!

空军一号空军一号钓鱼时,一直看着鱼漂,其他什么事情都不做,直到鱼上钩,完成钓鱼,才去做别的事情
空军二号空军二号钓鱼时,一会看一下鱼漂有没有动,一会跟旁边的其他钓鱼佬讲话,一会玩玩手机,循环往复的进行鱼漂的观察。
空军三号空军三号是装备党,一次性带着100个鱼竿,哪个上钩了就收哪个杆
空军四号空军四号很聪明,在鱼漂上绑了一个铃铛,如果鱼上钩,铃铛回响,那么空军四号在铃铛响之前就可以做自己的事情
空军五号

空军五号带着他的兄弟一起钓鱼,他提出去钓鱼但是他不参与,实际上他把鱼竿给了兄弟之后,他就去干别的事情了,等着吃鱼了。

初识高级IO

我们通过空军一号、到空军五号不同的钓鱼习惯,初步学习了五种IO模型,我们可以感受到这五种钓鱼习惯的不同,对应的钓鱼效率是不一样的,显然,空军四号能够高效的钓鱼、空军一号太过死板,钓鱼效率低下。同样的,五种IO模型也是如此,各自效率、复杂性和适用场景方面都有所差异。所以在实际应用中,需要根据具体需求和环境选择合适的IO模型!!!

那什么是高级IO呢?

高级IO技术涉及在应用程序与操作系统、硬件设备之间的高效数据交换。其目标是通过优化等待和拷贝过程,提高IO操作的效率。也就是在计算机系统中进行输入和输出操作时使用的一种更高级的接口和技术。

 为什么需要高级IO呢?因为对于IO而言,必不可少的是对数据的获取进行等待,而这个等待一般会造成IO的效率低下,所以我们需要进行不同的等待策略,来实现高级IO

同步IO和异步IO

  • 同步IO:只要参与了IO的基本过程,即等待和拷贝其一,就可以视为同步IO。
  • 异步IO:不参与IO的过程,既不等待也不拷贝。

也就是说,阻塞IO、非阻塞IO、IO多路复用、信号驱动IO本质上都是同步IO,因为他们进行了IO的动作,而异步IO他把IO的行为转交给了别的模块进行IO,所以不为同步IO。

值得注意的是:这里的同步、异步IO的区分是以IO的概念作为出发点的,也就是 等待+拷贝 。

而我们在多线程的同步与互斥中提到的同步IO是对于IO这个行为进行区分的,比如读写的过程。

1.再谈五种IO模型

1.1.阻塞IO

阻塞IO:在内核将数据准备好之前,系统调用会一直等待数据。并且所有的套接字,默认都是阻塞方式。

如图我们也可以看到,recvfrom就是一条路走到黑,只有获取到数据才继续走后续的代码模块!!! 

1.2.非阻塞IO

非阻塞IO:如果内核还没有将数据准备好,系统调用会直接返回,返回值为EWOULDBLOCK错误码。

非阻塞式IO需要我们轮询调用recvfrom,这会造成CPU的开销,但是收到EWOULDBLOCK错误码和到下一层循环的recvfrom之前,我们可以调用其他的代码模块!!!


非阻塞IO的代码实现

首先我们要知道,对于任何一个文件描述符,默认都是阻塞式IO。另外fcntl函数主要用于对文件描述符进行各种控制操作。

#include <iostream>
#include <unistd.h>
#include <fcntl.h>

void SetNoneBlock(const int fd)
{
    // 获取当前文件描述符的属性
    int f1 = fcntl(fd, F_GETFL);
    if (f1 < 0)
    {
        std::cerr << "fcntl failed" << std::endl;
        exit(0);
    }
    // 对f1进行选项的增加 ,设置为非阻塞的 
    fcntl(fd, F_SETFL, fl | O_NONBLOCK);
}

int main()
{
    // 将键盘对应的文件描述符设置为非阻塞
    SetNoneBlock(0);
    while (1)
    {
        char buffer[1024];
        ssize_t n = read(0, buffer, sizeof(buffer) - 1);
        if (n > 0)
        {
            buffer[n] = 0;
            std::cout << "echo# " << buffer << std::endl;
        }
        else if(n == 0)
        {
            std::cout<<"all data are received"<<std::endl;
        }
        else
        {
            // 处于非阻塞时,read的返回值也为-1,
            // 这时会出现不知道是数据未就绪还是read错误的二义性问题

            // 因此我们借助errno的设置
            if (errno == EWOULDBLOCK || errno == EAGAIN)
            {
                std::cout << "none data, none block test..." << std::endl;
            }
            else if (errno == EINTR)    // 表示IO被信号中断
            {
                std::cout << "read interrupted by singal, trt again..." << std::endl;
            }
            else
            {
                std::cout << "read error" << std::endl;
                break;
            }
        }
        sleep(2);
    }
}

1.3.信号驱动IO

信号驱动IO:内核将数据准备好的时候,会发出SIGIO信号通知进程进行IO操作。

信号驱动IO的机制是通过告知内核,当数据到达缓存区后,发送信号给当前进程,接着在调用recvfrom,减少等待的时间。并且等待信号的这段时间,可以执行其他的代码模块!!!

1.4.IO多路复用

IO多路复用:将多个IO通道注册到一个事件管理器中,然后通过阻塞方式等待事件的发生。一旦有事件发生(如有数据可读或可写),线程就会被唤醒,然后可以针对具体的事件进行处理。

我们设置select、poll、epoll来监听大量的文件描述符,如果监听到数据就绪,就去调用recvfrom,这时数据就绪就不会造成recvfrom的等待,而是直接进行拷贝。

这时我们就能够理解高效在:select、poll、epoll可以实现单个线程(执行流)来监听大量的IO通道,进而实现高并发。

具体的讲解我们在下一篇博客具体学习!!!

1.5.异步IO

异步IO:发起IO,但是将IO的行为交由操作系统来进行处理,当数据未就绪时,由操作系统进行等待,当数据就绪时,让操作系统进行拷贝

通过aio_read机制将原本当前进程需要进行的IO行为,转交给操作系统进行。

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

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

相关文章

美图公司AI短片创作工具MOKI工具震撼发布:自动生成助力创作者高效产出

美图公司在2024年6月12日举办的第三届美图影像节上&#xff0c;正式发布了全新的AI短片创作工具MOKI。这款工具以其独特的功能和高效的创作流程&#xff0c;为视频创作领域注入了新的活力。 MOKI的核心功能在于其能够自动生成分镜图&#xff0c;并将其转换为视频素材。用户只需…

Dorkish:一款针对OSINT和网络侦查任务的Chrome扩展

关于Dorkish Dorkish是一款功能强大的Chrome扩展工具&#xff0c;该工具可以为广大研究人员在执行OSINT和网络侦查任务期间提供强大帮助。 一般来说&#xff0c;广大研究人员在执行网络侦查或进行OSINT信息收集任务过程中&#xff0c;通常会使用到Google Dorking和Shodan&…

基于JSP的超市管理系统

你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP MyBatis 工具&#xff1a;IDEA/Eclipse、Navicat、Maven 系统展示 员工管理界面图 管…

[vue2]深入理解vuex

本节内容 概述初始化仓库定义数据访问数据修改数据处理异步派生数据模块拆分案例-购物车 概述 vuex是一个vue的状态管理工具, 状态就是数据 场景 某个状态在很多个组件使用 (个人信息)多个组件 共同维护 一份数据 (购物车) 优势 数据集中式管理数据响应式变化 初始化仓库 …

30字以内免费翻译维吾尔语,汉维翻译工具推荐,维吾尔文字母OCR识别神器《维汉翻译通》App!

维吾尔文OCR文字识别 《维汉翻译通》App内置的OCR技术&#xff0c;能够快速识别图片中的文字和字母&#xff0c;无论是路标、菜单还是书籍&#xff0c;都能迅速转换为用户所需的语言&#xff0c;让语言障碍不再是问题。针对维吾尔语更是进行了专门的优化&#xff0c;即便是手写…

【Ardiuno】实验ESP32单片机自动配置Wifi功能(图文)

这里小飞鱼按照ESP32的示例代码&#xff0c;实验一下wifi的自动配置功能。所谓的自动配置&#xff0c;就是不用提前将wifi的名称和密码写到程序里&#xff0c;这样可以保证程序在烧录上传后&#xff0c;可以通过手机端的软件来进行配置&#xff0c;可以避免反复修改代码&#x…

事件、方法实现 on_radioGreen_clicked ,on_chkBoxUnder_clicked,Qfont,QPalette

Vertical Layout 、Horizontal Layout 实验窗体自适应布局 接上篇界面布局&#xff0c; 实验checkBox、radioBox 的事件槽&#xff0c; 使用Qfont组件变更纯文本框QPlainTextEdit中字体的下划线、加粗、斜体效果 使用调色板组QPalette变更纯文本框QPlainTextEdit中文本颜色 UI…

Qt全局快捷键QGlobalHotKey的自研之路

这两天对Qt的快捷键格外感兴趣。 前两天在使用QHotKey的过程中&#xff0c;发现不能定义小键盘键盘码&#xff0c;自己二次修改了该库之后已经可以设置小键盘快捷键了。文章在这里&#xff1a;Qt第三方库QHotKey设置小键盘数字快捷键。 昨天突发奇想&#xff1a;目前所有的快…

20240613解决飞凌的OK3588-C的核心板的USB3.0接口不读U盘的问题

20240613解决飞凌的OK3588-C的核心板的USB3.0接口不读U盘的问题 2024/6/13 15:21 缘起&#xff0c;由于USB3.0的CC芯片在飞凌的OK3588-C的开发板的底板上&#xff0c;一切正常。 如果你单独使用核心板&#xff0c;很容易出现这个问题【省成本没有使用CC芯片】&#xff1a;不读U…

VScode中连接并使用docker容器

前提条件&#xff1a; 1.在windows下安装Docker Desktop(方法可见下面的教程) Docker Desktop 安装使用教程-CSDN博客 2.在vscode安装3个必备的插件 3.先在ubuntu中把docker构建然后运行 4.打开vscode&#xff0c;按下图顺序操作 调试好之后上传到git上&#xff0c;然后后面…

随心笔记,第六更

目录 一、 三步构建 XML转成java bean 1.XML转XSD 2.XSD转JavaBean 3.jaxb 工具类 4.测试 &#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是「Leen」。刚工作几年&#xff0c;想和大家一同进步&am…

Java中Transactional在不同方法间的穿透性,rollbackFor参数含义

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 在Java开发中&#xff0c;经常会遇到需要在一个事务中执行多个操作的场景。为了确保这些操作的原子性&#xff0c;可以使用Spring框架提供的Transactional注解来实现事务管理。然而&#xff0c;在实际开发过程中&…

Centos: ifconfig command not found且ip addr查不到服务器IP

前段时间部门新派发了服务器&#xff0c;让我过去使用U盘装机&#xff0c;装完后使用ifconfig查不到服务器IP地址&#xff0c;ip addr也是查不到 ifconfig&#xff1a;command not found (这两个图片先用虚拟机的替代一下) 在网上找资料(CSDN&#xff0c;博客园&#xff0c;知乎…

【权威出版/稳定检索】2024年气象应用、勘查与灾害应急国际会议(AEMT 2024)

2024 International Conference on Meteorological Applications, Exploration, and Disaster Emergency Response 2024年气象应用、勘查与灾害应急国际会议 【会议信息】 会议简称&#xff1a;AEMT 2024 大会时间&#xff1a;请查看官网 截稿时间&#xff1a;点击查看 大会地…

自动化办公03 用xlrd和xlwt库操作excel.xls文件(老版本)

目录 一、读操作 二、写操作 三、设置单元格格式 0.综合案例 1.设置行高和列宽 2.设置字体样式 3.设置边框样式 4.设置对齐方式 5.设置背景颜色 6.合并单元格 四、 xlutils修改Excel⽂件内容 1.安装 2.使用 一、读操作 import xlrd# 1. 打开excel文件 wb xlrd.op…

MT7981B+MT7976C+MT7531A RF定频测试方法

1、从下面网址下载QA软件包&#xff0c;然后在WIN系统下安装QA环境。 https://download.csdn.net/download/zhouwu_linux/89428691?spm1001.2014.3001.5501 在WINDOWS 7系统下先安装WinPcap_4_1_3.exe。 2、搭建硬件环境&#xff0c;电脑先连接仪器&#xff0c;主板网络与电…

Deepstream用户手册——DeepStream应用及配置文件

DeepStream参考应用 - DeepStream-app 应用架构 下图显示了NVIDIADeepStream参考应用程序的架构。 DeepStream 参考应用程序是一个基于 GStreamer 的解决方案&#xff0c;由一组封装低级 API 以形成完整图形的GStreamer插件组成。参考应用程序能够接受来自各种来源的输入&…

算法day28

第一题 295. 数据流的中位数 本题我们是求解给定数组的中位数。且由于需要随时给数组添加元素&#xff0c;所以我们要求解该动态数组的中位数&#xff0c;所以本题最关键的就是维护数组在添加元素之后保持有序的排序&#xff0c;这样就能很快的求解中位数&#xff1b; 解法&am…

提升消费者满意度的五星售后服务认证

在当今竞争激烈的市场环境中&#xff0c;消费者满意度是企业取得成功的重要因素。五星售后服务认证作为一种权威性认证&#xff0c;可以显著提高消费者满意度&#xff0c;增强企业的竞争力。本文将从四个方面探讨五星售后服务认证如何提高消费者满意度。 五星售后服务认证是由国…

RedHat9 | iSCSI磁盘配置与管理

一、实验环境 1、iSCSI介绍 iSCSI&#xff08;Internet Small Computer System Interface&#xff09;是一种基于因特网及SCSI-3协议下的存储技术&#xff0c;也称为IP-SAN。iSCSI是由IETF&#xff08;Internet Engineering Task Force&#xff09;提出&#xff0c;并于2003年…