Linux操作系统提供了五种主要的IO(输入/输出)模型
Linux操作系统提供了五种主要的IO(输入/输出)模型,这些模型旨在优化应用程序对输入输出操作的管理和处理。以下是关于这五种IO模型的详细介绍。
一、阻塞IO(Blocking IO)
阻塞IO是最常见、最传统的IO模型。在这种模型中,当用户进程发起一个IO请求后,内核会一直等待,直到IO操作完成并返回结果。在此期间,用户进程会被阻塞,无法进行其他操作。
1. 工作原理
当用户进程调用如recvfrom
这样的系统调用时,内核会开始IO的第一个阶段:准备数据。对于网络IO来说,很多时候数据在一开始还没有到达,比如还没有收到一个完整的UDP包。这时,内核会等待足够的数据到来。这个过程需要等待,也就是说数据被拷贝到操作系统内核的缓冲区中是需要一个过程的。而在用户进程这边,整个进程会被阻塞,直到内核等到数据准备好了,才会将数据从内核中拷贝到用户内存,然后返回结果,用户进程才解除阻塞状态,重新运行起来。
2. 特点
- 简单易用:阻塞IO模型易于理解和实现,开发者不需要处理复杂的IO状态检查和轮询。
- 效率不高:由于用户进程在IO操作期间被阻塞,无法执行其他任务,导致CPU资源利用率低。
- 适用场景:阻塞IO模型通常适用于单线程、同步、串行的应用程序,如文件传输、打印机等。
3. 示例
假设一个用户进程需要从套接字读取数据。在阻塞IO模型中,当用户进程调用recv
函数时,如果套接字缓冲区没有就绪数据包,进程状态将从TASK_RUNNING
切换至TASK_INTERRUPTIBLE
状态,并通过进程调度完成进程阻塞。同时,进程也会加入到套接字等待队列,等待数据到来后被唤醒。当网卡收到数据包后,通过DMA机制将数据包拷贝到内核空间RingBuffer,并通过中断机制将数据包拷贝至套接字接收缓冲区。套接字接收到数据包后,会唤醒等待队列中的休眠进程。进程被唤醒后继续完成用户空间和内核空间的数据同步,recv
函数成功返回。
二、非阻塞IO(Non-blocking IO)
非阻塞IO是在阻塞IO的基础上进行改进的一种IO模型。在这种模型中,当用户进程发起一个IO请求后,内核会立即返回一个错误码,表示IO操作还未完成。用户进程可以继续进行其他操作,随后再通过轮询的方式来查询IO操作是否完成。
1. 工作原理
当用户进程调用如recv
这样的非阻塞IO函数时,如果套接字缓冲区没有就绪数据包,recv
函数会立即返回EWOULDBLOCK
错误码。用户进程可以一直调用recv
函数,直到数据准备好为止。在非阻塞IO模型中,用户进程需要不断地询问内核数据是否就绪,也就是说非阻塞IO不会交出CPU,而会一直占用CPU。
2. 特点
- 避免阻塞:非阻塞IO模型允许用户进程在IO操作期间执行其他任务,提高了CPU资源的利用率。
- 轮询开销:由于用户进程需要不断地询问内核数据是否就绪,这会导致CPU占用率非常高,因此一般情况下很少使用while循环这种方式来读取数据。
- 适用场景:非阻塞IO模型适用于需要同时处理多个IO操作的应用程序,如服务器程序中的多客户端连接处理。
3. 示例
假设一个用户进程需要从套接字读取数据。在非阻塞IO模型中,当用户进程调用recv
函数时,如果套接字缓冲区没有就绪数据包,recv
函数会立即返回EWOULDBLOCK
错误码。用户进程可以一直调用recv
函数,直到数据准备好为止。在这个过程中,用户进程可以继续执行其他任务,如处理其他客户端的连接请求。当数据准备好后,用户进程再次调用recv
函数,成功读取数据。
三、IO复用(IO Multiplexing)
IO复用是指通过select
、poll
、epoll
等系统调用来监听多个文件描述符的IO事件。当某个文件描述符就绪时(一般是读就绪或者写就绪),内核会通知用户进程进行IO操作。
1. 工作原理
IO复用模型允许一个进程同时监视多个文件描述符,当其中任意一个文件描述符就绪时,就可以进行相应的IO操作。相比于阻塞IO和非阻塞IO,IO复用可以同时监听多个文件描述符,提高了IO效率。在Linux中,常用的IO复用模型有select
、poll
、epoll
等。
- select:通过位图实现IO复用,将socket注册到读、写或异常位图,通过
select
系统调用轮询位图,获取socket事件。成功获取到socket事件后,select
成功返回,此时可以通过接收函数读取socket缓冲区数据。 - poll:和
select
非常相似,主要区别为poll
将位图改成链表。poll
通过链表实现IO复用,将socket注册到poll_list
链表,通过poll
系统调用轮询链表,获取socket事件。成功获取到socket事件后,poll
成功返回,此时可以通过接收函数读取socket缓冲区数据。 - epoll:采用回调方式获取就绪socket事件,相比于
select
和poll
模型的轮询方式效率更高。通过epoll_ctl
系统调用注册socket事件至红黑树,当socket接收到数据后,通过回调函数将socket事件添加至就绪队列。调用epoll_wait
查询就绪队列就能获取到socket事件。
2. 特点
- 高效:IO复用模型可以同时监听多个文件描述符,提高了IO效率。
- 适用场景:IO复用模型适用于需要同时处理多个IO操作的应用程序,如服务器程序中的多客户端连接处理。
3. 示例
假设一个服务器程序需要同时处理多个客户端的连接请求。在IO复用模型中,服务器程序可以使用epoll
系统调用来监听所有客户端的连接请求。当某个客户端的连接请求到达时,epoll
会通知服务器程序进行相应的处理。服务器程序可以读取客户端发送的数据,并返回响应。这样,服务器程序就可以同时处理多个客户端的连接请求,提高了并发处理能力。
四、信号驱动IO(Signal-driven IO)
信号驱动IO是指用户进程通过signal
或sigaction
系统调用来注册一个信号处理函数。当IO操作完成时,内核会向用户进程发送一个SIGIO信号,用户进程在信号处理函数中进行IO操作。
1. 工作原理
用户进程首先注册一个SIGIO信号处理函数。当内核收到数据后,会发送SIGIO信号给用户进程。用户进程在信号处理函数中调用如recv
这样的函数来完成IO操作。
2. 特点
- 避免阻塞:信号驱动IO模型可以避免用户进程被阻塞,提高了IO效率。
- 复杂性:信号驱动IO模型需要处理信号处理函数的注册和调用,增加了程序的复杂性。
- 适用场景:信号驱动IO模型适用于需要处理大量IO操作且不希望被阻塞的应用程序。
3. 示例
假设一个用户进程需要从套接字读取数据。在信号驱动IO模型中,用户进程首先通过signal
或sigaction
系统调用来注册一个SIGIO信号处理函数。当内核收到数据后,会发送SIGIO信号给用户进程。用户进程在信号处理函数中调用recv
函数来读取数据。这样,用户进程就可以在不被阻塞的情况下处理IO操作。
五、异步IO(Asynchronous IO)
异步IO是指当用户进程发起一个IO请求后,内核会立即返回,表示IO操作已经开始。当IO操作完成后,内核会通知用户进程,用户进程在此时才进行IO操作。
1. 工作原理
在异步IO模型中,用户进程发起IO请求后,内核会立即返回。用户进程可以继续执行其他任务。当IO操作完成后,内核会通过通知机制(如回调函数)来通知用户进程。用户进程在收到通知后,再进行IO操作。
2. 特点
- 高效:异步IO模型允许用户进程在IO操作期间执行其他任务,提高了CPU资源的利用率。
- 复杂性:异步IO模型需要处理通知机制和回调函数的注册和调用,增加了程序的复杂性。
- 适用场景:异步IO模型适用于需要处理大量IO操作且对响应时间有严格要求的应用程序。
3. 示例
假设一个用户进程需要从套接字读取数据。在异步IO模型中,用户进程发起IO请求后,内核会立即返回。用户进程可以继续执行其他任务。当数据准备好后,内核会通过回调函数来通知用户进程。用户进程在收到通知后,调用如recv
这样的函数来读取数据。这样,用户进程就可以在不被阻塞的情况下处理IO操作,并且能够在数据准备好后立即进行处理。
总结
Linux操作系统提供了五种主要的IO模型:阻塞IO、非阻塞IO、IO复用、信号驱动IO和异步IO。每种模型都有其优缺点和适用场景。开发者在选择IO模型时,需要根据应用程序的具体需求和性能要求来进行权衡和选择。
- 阻塞IO:简单易用但效率不高,适用于单线程、同步、串行的应用程序。
- 非阻塞IO:避免阻塞但轮询开销大,适用于需要同时处理多个IO操作的应用程序。
- IO复用:高效且适用于多客户端连接处理的应用程序。
- 信号驱动IO:避免阻塞但增加了程序的复杂性,适用于需要处理大量IO操作且不希望被阻塞的应用程序。
- 异步IO:高效且对响应时间有严格要求的应用程序。
相关文章:
Linux操作系统提供了五种主要的IO(输入/输出)模型
Linux操作系统提供了五种主要的IO(输入/输出)模型,这些模型旨在优化应用程序对输入输出操作的管理和处理。以下是关于这五种IO模型的详细介绍。 一、阻塞IO(Blocking IO) 阻塞IO是最常见、最传统的IO模型。在这种模型…...

基于深度学习的花卉识别系统
简介: 基于Python的花卉识别分类系统利用深度学习和计算机视觉技术,能够准确识别和分类各种花卉,如玫瑰、郁金香和向日葵等。这种系统不仅有助于植物学研究和园艺管理,还在生态保护、智能农业和市场销售等领域展现广泛应用前景。随…...

【斯坦福CS144】Lab0
一、实验目的 1.初步了解计算机网络,准备实验所需的材料和环境; 2.掌握基础实验方法; 3.动手实现网络功能。 二、实验内容 1.下载实验所需的资料,安装虚拟机,配置环境; 2.获取一个网页; …...

关于Mybatis中,IPage<PO>转换成IPage<VO>的问题
以下是一个比较常见通用的一个查询并且为单表查询,在开发初期,或者项目不是很复杂的时候,或者一开始项目框架就规划好的情况下,通常我们都会封装。 在我们的项目中,这部分代码其实是自动生成的,足以满足大…...

使用idea和vecode创建vue项目并启动(超详细)
一、idea创建vue项目 创建项目之前先下载好插件 新建项目找到vue生成器 写好名称,找到自己需要存放的地址,node解释器安装方式可以看我上一个博客,vueCLI是选择vue的版本,我们可以使用idea自带的vue版本默认是vue3,创…...

C#|.net core 基础 - 删除字符串最后一个字符的七大类N种实现方式
今天想通过和大家分享如何删除字符串最后一个字符的N种实现方法,来回顾一些基础知识点。 01第一类、字符串方式 这类方法是通过string类型自身方法直接实现。 1、Substring方法 相信大多数人第一个想到的可能就是这个方法。Substring方法是字符串内置方法&#…...

成都睿明智科技有限公司怎么样靠谱吗?
随着短视频与直播的深度融合,抖音电商凭借其强大的流量入口、精准的算法推荐以及便捷的购物体验,迅速崛起。对于传统企业和新兴品牌而言,这无疑是一个不可多得的机遇。然而,如何在这片红海中脱颖而出,就需要借助专业的…...

docker简述
1.安装dockers,配置docker软件仓库 安装,可能需要开代理,这里我提前使用了下好的包安装 启动docker systemctl enable --now docker查看是否安装成功 2.简单命令 拉取镜像,也可以提前下载使用以下命令上传 docker load -i imag…...
第27周:Transformer实战:文本分类
目录 前言 一、前期准备 1.1 环境安装 1.2 加载数据 二、数据预处理 2.1 构建词典 2.2 生成数据批次和迭代器 2.3 构建数据集 三、模型构建 3.1 定义位置编码器 3.2 定义Transformer模型 3.3 初始化模型 3.4 定义训练函数 3.5 定义评估函数 四、训练模型 4.1 模…...

在QT中将Widget提升为自定义的Widget后,无法设置Widget的背景颜色问题解决方法
一、问题 在Qt中将QWidget组件提升为自定义的QWidget后,Widget设置的样式失效,例如设置背景颜色为白色失效。 二、解决方法 将已经提升的QWidget实例对象,脱离父窗体的样式,然后再重新设置自己的样式。...

【学习笔记】手写一个简单的 Spring IOC
目录 一、什么是 Spring IOC? 二、IOC 的作用 1. IOC 怎么知道要创建哪些对象呢? 2. 创建出来的对象放在哪儿? 3. 创建出来的对象如果有属性,如何给属性赋值? 三、实现步骤 1. 创建自定义注解 2. 创建 IOC 容器…...

日记学习小迪安全27
感觉复制粘贴没有意思,而且还有点浪费时间,主要是学习,不是复制,那就复制别人的吧 第27关就参考这篇文章吧,以下大部分内容都是参考以下文章(侵权删除) 第27天:WEB攻防-通用漏洞&a…...
【React】类组件和函数组件
构建组件的方式 函数式组件(function)createElement(不建议使用)类组件形式创建(不建议使用) 对于 React 的理解 React, 用于构建用户界面的JavaScript库,本身只提供了Ul层面的解决方案。&am…...
Spring Boot应用开发
Spring Boot是一个基于Spring框架的开源Java框架,旨在简化新Spring应用的初始化和开发过程。它通过提供各种默认配置,减少了繁琐的配置,使开发者能够专注于业务逻辑的实现。本文将介绍Spring Boot的基本概念、优点、关键特性以及如何构建一个…...

mysql事务使用和事务隔离级别与sqlserver的比较
在 MySQL 中,事务 (Transaction) 是一个将一组 SQL 语句作为一个整体执行的机制。事务确保要么所有操作都执行成功,要么在遇到错误时回滚到之前的状态,从而保证数据库数据的一致性和完整性。 事务的四大特性(ACID) 事…...

双光吊舱图像采集详解!
一、图像采集 可见光图像采集: 使用高性能的可见光相机,通过镜头捕捉自然光或人工光源照射下的目标图像。 相机内部通常配备有先进的图像传感器,如CMOS或CCD,用于将光信号转换为电信号。 红外图像采集: 利用红外热…...

1688商品详情关键词数据-API
要利用 Python 爬虫采集 1688 商品详情数据,需要先了解 1688 网站的页面结构和数据请求方式。一般使用 requests 库请求网站的数据,使用 BeautifulSoup 库解析网页中的数据。 以下是一个简单的 Python 爬虫采集 1688 商品详情数据的示例代码:…...

vue 的属性绑定
双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute,应该使用 v-bind 指令。 <template> <div v-bind:class"boxClass" v-bind:id"boxId"> </div> </template><script> export default{da…...
【附源码】Python :打家劫舍
系列文章目录 Python 算法学习:打家劫舍问题 文章目录 系列文章目录一、算法需求二、解题思路三、具体方法源码方法1:动态规划(自底向上)方法2:动态规划(自顶向下)方法3:优化的动态…...

YOLO11改进 | 注意力机制| 对小目标友好的BiFormer【CVPR2023】
秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 本文介绍了一种新颖的动态稀疏注意力机制…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...