Linux下I/O复用模型

【Linux】I/O多路复用模型 阅读详情

以下内容引述至《Linux/Unix系统编程手册》

整体概览

常见的程序使用的I/O模型都是单个进程每次只在一个文件描述符上执行I/O操作,每次I/O系统调用会阻塞直到完成数据传输。
对于许多应用来说,传统的阻塞式I/O模型已经足够了,但这不代表所有的应用都能得到满足。

  • 如果可能的话,以非阻塞的方式检查文件描述符上是否可进行I/O操作
  • 同时检查多个文件描述符,看它们中的任何一个是否可以执行I/O操作
    满足这些技术需求的方案是:
    非阻塞式I/O 和 多进程或多线程技术

非阻塞式I/O可以让我们周期性地检查(“轮询”)某个文件描述符上是否可执行I/O操作。
由于非阻塞式I/O和多进(线)程都有各自的局限性,下列备选方案往往更可取:

  • I/O多路复用允许进程同时检查多个文件描述符以找出它们中的任何一个是否可执行I/O操作。系统调用select()和poll()用来执行I/O多路复用
  • 信号驱动I/O是指当时有输入或者数据可以写到指定的文件描述符上时,内核向请求数据的进程发送一个信号。进程可以处理其他的任务,当I/O操作可执行时通过接受信号来获取通知。当同时检查大量的文件描述符是,信号驱动I/O相比select()和poll()有显著的性能提升
  • epoll API是Linux 专有的特性,首次出现是在Linux 2.6版本中。同I/O多路复用API一样,epoll API允许进程同时检查多个文件描述符时,看其中任意一个是否能执行I/O操作。同信号驱动I/O一样,当同时检查大量文件描述符时,epoll能提供更好的性能。

实际上I/O多路复用、信号驱动I/O以及epoll都是用来实现同一目标的技术——同时检查多个文件描述符,看它们是否准备好了执行I/O操作。
文件描述符就绪状态的转化是通过一些I/O事件来触发的,比如输入数据到达,套接字连接建立完成,或者是之前满载的套接字发送缓冲区在TCP将队列中的数据传送到对端之后有了剩余空间。

技术选型

  • 系统调用select() 和 poll() 在Unix系统中已经存在很长的时间了。同其他技术相比,他们主要的优势在于可移植性,主要缺点在于当同时检查大量的(数百或数千个)文件描述符时性能延展性不佳
  • epoll API的关键技术优势在于它能让应用程序高效地检查大量的文件描述符
  • 同epoll一样,信号驱动I/O可以让应用程序高效地检查大量的文件描述符。但是epoll有一些信号驱动I/O所没有的优点
    1. 避免了处理信号的复杂性
    2. 我们可以指定想要检查的事件类型(即,读就绪或者写就绪)
    3. 我们可以选择以水平触发或边缘触发的形式来通知进程

水平出发和边缘触发

我们先区分两种文件描述符准备就绪的通知模式:

  • 水平触发通知:如果文件描述符上可以非阻塞式地执行I/O系统调用,此时认为它已经就绪
  • 边缘触发通知:如果文件描述符自上次状态检查以来有了新的I/O活动,此时需要触发通知

使用水平触发和边缘触发通知模型

I/O模式水平触发边缘触发
select(), poll()*
信号驱动*
epoll**

当采用水平触发通知时,我们可以在任意时刻检查文件描述符的就绪状态。这表示当我们确定了文件描述符处于就绪状态时(比如存在有输入数据),就可以对其执行一些I/O操作,然后重复检查we年描述符,看看是否仍然处于就绪态(比如还有更多的输入数据),此时我们就能执行更多的I/O,以此类推。

于此相反的是,当我们采用边缘触发时,只有当I/O事件发生时我们才会收到通知,在另一个I/O事件到来前我不会收到任何新的通知。另外当文件描述符收到I/O事件通知时,通常我们并不知道要处理多少I/O。因此,采用边缘触发通知的程序通常要按照如下规则来设计

  • 在接收到一个I/O事件通知后,程序在某个时刻应该在响应的文件描述符上尽可能多地执行I/O操作,如果程序没那么做,那么就可能失去执行I/O的机会。因为直到产生另一个I/O事件为止,在此之前程序都不会再接收到通知了,因此也就不知道此时应该执行I/O操作。这将导致数据丢失或者程序中出现阻塞。当我们确定了文件描述符是就绪态时,此事可能并不适合马上执行所有的I/O操作。问题的原因在于如果我们仅对一个文件描述符执行大量的I/O操作,可能会让其他文件描述符处于饥饿状态
  • 如果程序采用循环来对文件描述符执行尽可能多的I/O,而文件描述符又被置为可阻塞的,那么最终当没有更多的I/O可执行时,I/O系统调用就会阻塞。基于这个原因,每个被检查的文件描述符通常都应该被置为非阻塞模式,在得到I/O时间通知后重复执行I/O操作,直到响应的系统调用以错误码EAGAIN或EWOULDBLOCK的形式失败

采用非阻塞I/O

  • 非阻塞I/O通常和提供有边缘触发通知机制的I/O模型一起使用
  • 如果多个进程(或线程)在同一个打开的文件描述符上执行I/O操作,那么从某个特定进程的角度来看,文件描述符的就绪状态可能会在通知就绪和执行后续I/O调用之间发生改变。结果就是一个阻塞式的I/O调用将阻塞,从而防止进程检查其他的文件描述符
  • 尽管水平触发模式的API比如select() 或 poll() 通知我们流式套接字的文件描述符已经写就绪了,如果我们在单个write()或send()调用中写入足够大块的数据,那么该调用将阻塞
  • 在非常罕见的情况下,水平触发型的API比如select()和poll(),会返回虚假的就绪通知——他们会错误通知我们文件描述符已经就绪了。

I/O多路复用

I/O多路复用允许我们同时检查多个文件描述符,看其中任意一个是否可执行I/O操作。我们可以采用两个功能几乎相同的系统调用来执行I/O多路复用操作。

select()系统调用

系统调用select()会一直阻塞,直到一个或多个文件描述符集合称为就绪态

#include <sys/time.h>
#include <sys/select.h>
int select(int ndfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
			struct timeval * timeout);

fd_set 文件描述符集合
参数readfsd, writefds 以及 exceptfds 都是指向文件描述符集合的指针,所指向的数据类型是fd_set

  • readfds 是用来检测输入是否就绪的文件描述符集合
  • writefds 是用来检测输出是否就绪的文件描述符集合
  • exceptfds 是用来检测异常情况是否发生的文件描述符集合

在Linux上,一个异常情况只会在下面两种情况下发生

  • 连接到处于信号包模式下的伪终端主设备上的从设备状态发生了改变;
  • 流式套接字上接收到了带外数据

通常,数据类型fd_set以位掩码的形式来实现

#include <sys/select.h>
// 将fdset所指向的集合初始化为空
void FD_ZERO(fd_set *fdset); 
// 将文件描述符fd添加到由fdset所指向的集合中
void FD_SET(int fd, fd_set *fdset);
// 将文件描述符fd从fdset所指向的结婚中移除
void FD_CLR(int fd, fd_set *fdset);
// 如果文件描述符fd是fdset所指向的集合中的成员,FD_ISSET()返回true
int FD_ISSET(int fd, fd_set *fdset);

文件描述符集合由一个最大容量限制,由常量FS_SETSIZE来决定。在Linux上,该常量的值为1024

select()的返回值
-1 表示错误发生
0 表示超时
正整数表示有1个或多个文件描述符已达到就绪态,返回值表示处于就绪态的文件描述符个数。

poll() 系统调用

系统调用poll()执行的任务同select()很相似。两者间主要的区别是我们如何指定待检查的文件描述符。

#include <poll.h>
int poll(strcut pollfd[], nfds_t nfds, int timeout);

参数fds列出了我们需要poll()来检查的文件描述符。定义如下

strcut pollfd {
	int fd;
	short evnets;
	short revents;
};

参数nfds指定了数组fds中元素的个数。数据类型nfds_t 实际为无符号整型
pollfd结构体中的events和revents字段都是位掩码。调用者初始化events来指定需要描述符fd做检查的事件。当poll()返回时,revents被设定以此来表示该文件描述符上实际发生的事件。
返回值同select()函数,但是一个文件描述符只统计一次,select同一个文件描述符统计多次。

文件描述符就绪

如果对I/O函数的调用不会阻塞,而不论该函数是否能够实际传输数据,此时文件描述符(未指定O_NONBLOCK标志)被认为是就绪的。
select()和poll()只会告诉我们I/O操作是否阻塞,而不是高数我们到底能够成功传输数据。

  • select()这一列表示文件描述符是否被标记为可读®,可写(w)还是有异常情况(x)
  • poll()这一列表示在revents字段中返回的位掩码。这这些表格中,我们忽略POLLRDNORM、POLLWRNORM、POLLRDBAND以及POLLWRBAND

普通文件
代表普通文件的文件描述符总是被select()标记为可读和可写。对于poll()来说,则会在revents字段中返回POLLIN和POLLOUT标志

select() 和 poll() 比较

实现细节

在linux内核层面,select() 和 poll() 都使用了相同的内核poll例程集合。这些poll例程有别于系统调用poll()本身。每个例程都返回有关单个文件描述符就绪的信息。就绪信息以位掩码表示,其值同poll()系统调用中返回的revents字段中的比特值相关
为了实现select(),我们使用一组宏将内核poll例程返回的信息转化为由select()返回的与之对应的事件类型

#define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR)
#define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
#define POLLEX_SET (POLLPRI)
区别
  • select()所使用的数据类型fd_set对于被检查的文件描述符数量有一个上限限制,poll()没有
  • select()参数fd_set同时也是保存调用结果的地方,如果要在循环中重复调用select()的话,我们必须每次都要重新初始化fd_set,而poll()通过独立的两个字段events(针对输入)和revents(针对输出)来处理,从而避免每次都要重新初始化参数
  • select()提供的超时精度比poll()提供的超时精度比poll()提供的超时精度高
  • 如果其中一个被检查的文件描述符关闭了,通过在对应的revents字段中设定POLLNVAL标记,poll()会准确告诉我们哪一个文件描述符关闭了。而select()只会返回-1,并设置错误码EBADF
性能

当满足如下两条任意一条时,性能接近

  • 待检查的文件描述符范围较小
  • 有大量的文件描述符待检查,但是它们分布得很密集(0到某个上限之间)
    然而,当文件描述符集合很稀疏的时候,poll()表现得比select()要好很多。当使用poll()时,只需要指定我们感兴趣的文件描述符即可,内核只会去检查这些指定的文件描述符
存在的问题
  • 每次调用select()或poll(),内核都必须检查所有指定的文件描述符,看他们是否处于就绪态。当检查大量处于密集范围内的文件描述符时,该操作耗费的时间将大大超过接下来的操作
  • 每次调用select()或poll()时,程序都必须传递一个表示所有需要被检查的文件描述符的数据结构到内核,内核检查过描述符后,修改这个数据结构并返回给程序。对于poll()而言,随着待检查的文件描述符数量的增加,传递给内核的数据结构大小也会随之增加。当检查大量文件描述符时,从用户空间到内核空间来回拷贝这个数结构将占大量的CPU时间。对于select()来说,这个数据结构的大小固定为FD_SETSIZE,与待检查的文件描述符数量无关
  • select()或poll()调用完成后,程序必须检查返回的数据结构中的每个元素,一次查明哪个文件描述符处于就绪态了

信号驱动I/O

在I/O多路复用中,进程时通过系统调用(select()或poll())来检查文件描述符上是否可以执行I/O操作。而在信号驱动I/O中,当文件描述符上可执行I/O操作时,进程请求内核为自己发送一个信号。之后进程就可以执行其他的任务直到I/O就绪为止。
过程如下:

  1. 为内核发送的通知信号安装一个信号处理例程,默认情况下,这个通知信号为SIGIO
  2. 设定文件描述符的属主,也就是当文件描述符上可执行I/O时会收到通知信号的进程或进程组。通常我们让调用进程称为属主。设定属主可通过fcntl()的F_SETOWN操作来完成
  3. 通过设定O_NONBLOCK标志使能非阻塞I/O
  4. 通过打开O_ASYNC标志使能信号驱动I/O
  5. 调用进程现在可以执行其他的任务了,当I/O操作就绪时,内核为进程发送一个信号,然后调用信号处理例程
  6. 信号驱动I/O提供的是边缘触发通知,这表示一旦进程被通知I/O就绪,就应该进口嫩更多地执行I/O

优化信号驱动I/O的使用

想要全部利用信号驱动I/O的优点,可以通过下面两个步骤

  • 通过专属于Linux的fcntl() F_SETSIG操作来指定一个实时信号,当文件描述符上的I/O就绪时,这个实时信号应该取代SIGIO被发送;
  • 使用sigaction()安装信号处理例程时,为前一步中使用的实时信号指定SA_SIGINFO标记

epoll编程接口

同I/O多路复用和信号驱动I/O一样,Linux的epoll API可以检查多个文件描述符上的I/O就绪状态。epoll API的主要优点如下:

  • 当检查大量的文件描述符时,epoll的性能延展性比select()和poll()高很多
  • epoll API既支持水平触发也支持边缘触发,与之相反,select()和poll()只支持水平触发,而信号驱动I/O只支持边缘触发

性能表现上,epoll同信号驱动I/O相似,但是epoll有一些胜过信号驱动I/O的优点

  • 可以避免复杂的信号处理流程
  • 灵活性高,可以指定我们希望检查的事件类型

epoll API的核心数据结构称为epoll实例,它和一个打开的文件描述符相关联。这个文件描述符不是用来做I/O操作的,相反,它是内核数据结构的句柄,这些内核数据结构实现了两个目的

  • 记录了在进程中声明过的感兴趣的文件描述符列表—— interest list
  • 维护了处于I/O就绪态的文件描述符列表—— ready list

epoll API由以下3个系统调用组成

  • 系统调用epoll_create()创建一个epoll 实例,返回代表该实例的文件描述符
  • 系统调用epoll_ctl() 操作同epoll 实例相关联的兴趣列表
  • 系统调用epoll_wait() 返回与 epoll 实例相关联的就绪列表中的成员

当我们通过epoll_create() 创建一个epoll实例时,内核在内存中创建一个新的i-node并打开文件描述,随后在调用进程中为打开的这个文件描述分配一个新的文件描述符。同epoll实例的兴趣列表相关联的是打开的文件描述,而不是epoll 文件描述符

边缘触发

epoll默认是水平触发,表示epoll会告诉我们何时能在文件描述符上以非阻塞的方式执行I/O操作。这同poll() 和 select() 所提供的通知类型相同
epoll API还可以通过边缘触发方式进行通知——也就是说,会告诉我们自从上一次epoll_wait()以来文件描述符上是否已有I/O活动了。使用epoll的边缘触发通知在语义上类似于信号驱动I/O,只是如果有多个I/O事件发生的话,epoll会将他们合并成一次单独的通知,通过epoll_wait()返回,而在信号驱动I/O中可能会产生多个信号

Linux I/O多路复用——select模型实现服务端Socket通信 目录 文件描述符简介 select模型理解 select缺点 select函数 函数原型 参数说明 fd_set 相关 程序实例 文件描述符简介 在进程中,每打开一个文件,操作系统就会创建相应的数据结构来描述这个文件,这就是描述文件的文件结构体,同时,在进程的PCB中,会有一个struct files_struct *files的指针,它实际上是指向一个指针数... 阅读详情

相关推荐

FAST-LIO2:论文和算法解析

本文介绍了FAST-LIO2算法:一种快速、鲁棒、通用的激光雷达-惯性里程计框架。FAST-LIO2基于高效的紧密耦合迭代卡尔曼滤波器,具有两个关键的新颖之处,可实现快速,稳健和准确的激光雷达导航(和测绘)。第一种方法是直接将原始点注册到地图上然后更新地图,而不提取特征。这样可以利用环境中的细微特征,从而提高准确性。消除手工设计的特征提取模块,也使其能够适应不同扫描模式的新兴激光雷达;

超爱吃小蛋糕的66的博客 1万+

linux: 五种IO模型(IO多路复用)

阻塞和非阻塞 侧重状态。 阻塞调用是指调用后对方一直没有给你回复,你一直等着,什么事都不能干。 非阻塞调用指在调用后一直没有给你回复,你每一段时间就问一次,你在这期间可以干别的。 同步和异步 侧重方式。 同步:甲方请求一次,乙方应答一次”这样的有序序列处理业务,只有当“一次请求一次应答”的过程结束才可以发生下一次的“一次请求一次应答”,那么就说他们采用的是同步。 异步:如果甲方只要有需要,就会发送请求,不管上次请求有没有得到乙方应答。而乙方只要甲方有请求就会接受,不是等这次请求处理完毕再接受甲方新请求

jiangxixiaolinzi的博客 341

第五章 PCIe介绍 5.1-5.7

为什么SSD要用PCIe接口?因为它快,比SATA快。通道,PCIe最多可以有32个通道。两个设备之间的PCIe连接,叫做一个Link。如下图,设备A和设备B是个双向连接,两个PCIe设备之间,有专门的发送和接收通道,数据可以同时往两个方向传输,PCIe Spec称这种工作模式为,可以理解为。和PCIe一样,SATA有独立的发送和接收通道。但与PCIe工作模式不一样,同一时间,SATA只有一条通道可以进行数据传输。这种工作模式称为。与SATA单通道不同,PCIe连接可以通过增加通道数扩展带宽。

fengbaobaola的博客 2969

linux常见的I/O复用技术汇总-select、poll、epoll

常见的I/O复用技术详解

深耕嵌入式领用多年, 致力于分享嵌入式领域技术! 388

手把手教你用野火FPGA开发板资料包安装ModelSim 10.5se(附破解教程)

本文提供了一份详细的指南,手把手教你为野火FPGA开发板安装和配置ModelSim 10.5se仿真工具。内容涵盖从前期准备、软件安装、许可证激活(学习用途)到环境验证的全过程,并简要介绍了如何与Xilinx Vivado开发套件集成,帮助初学者快速搭建稳定的FPGA仿真环境。

lstm7chronicler的博客 250

ATAC-seq差异分析实战:从原始数据到GO富集(R/Bioconductor全流程)

本文提供了ATAC-seq差异分析的完整R/Bioconductor实战流程,涵盖从原始数据准备、一致峰集构建、计数矩阵生成,到使用DESeq2进行差异可及性分析,以及差异峰的基因组注释与GO富集分析。文章详细讲解了关键步骤、参数设置和常见问题,旨在帮助研究者获得可靠且可解释的生物学结果。

weixin_29246195的博客 228

Linux编程--IO多路复用

IO多路复用是指通过一种机制,使得单个进程可以监控多个文件描述符的可读、可写和异常等事件。常见的IO多路复用技术包括:select、poll、epoll等。在实际应用中,IO多路复用可以提高程序的运行效率和性能,减少系统开销,降低系统资源的使用率。它广泛应用于网络编程、服务器开发、操作系统等领域,可以帮助开发人员更好地处理大量的网络连接和数据请求。

xinqi_1的博客 2403

化工设计软件:PDMS二次开发_(7).数据导入与导出技术

在某些复杂场景下,PDMS提供的标准API接口可能无法满足需求。此时,可以通过自定义API接口来实现特定的数据导入与导出功能。自定义设备导入API接口可以处理更复杂的设备数据格式。# 导入必要的库import pdms_api # 假设有一个PDMS API库# 定义自定义设备数据# 自定义设备导入API接口# 调用自定义设备导入API接口# 输出导入成功的消息print("自定义设备数据导入成功")在PDMS二次开发中,数据的导入与导出是关键的技术环节。

kkchenjj的博客 1484

select模式的IO的事件通知一定是准确的吗?

这里有一个C++写的SDK,封装了网络通信层,基于Select IO 网络IO模型;同一份代码,移植到到NDK和IOS下,线上反映的问题是,刚建立好TCP连接,然后执行Send操作,立即报EPIPE的错误; 报这个错误的原因解释是:1.尝试在一个未建立连接的socket上send 2.尝试在一个已经断开连接或者关闭写端通道的连接的socket上send; 但是先建立NIO的socket,然后使

会吃狼的鳄鱼 723

【100%通过率】华为OD机试真题 C 实现【最多等和不相交连续子序列】【2022.11 Q4 新题】

给定一个数组,我们称其中连续的元素为连续子序列,称这些元素的和为连续子序列的和。数组中可能存在几组连续子序列,组内的连续子序列互不相交且有相同的和。求一组连续子序列,组内子序列的数目最多。输出这个数目。

MISAYAONE的博客 1万+

【RT-DETR实战】159、改进九:知识蒸馏从YOLOv8教师模型学习

摘要: 本文探讨了知识蒸馏在RT-DETR目标检测模型中的应用挑战与实践经验。作者以YOLOv8作为教师模型,针对特征对齐、损失函数设计和训练策略等核心问题,提出了适配器模块、动态权重调整和多阶段训练等优化方案。文章重点分析了教师模型选择、特征图匹配、损失函数组合等关键环节的实战技巧,并总结了蒸馏模型部署时的注意事项。通过实验验证,作者指出知识蒸馏应关注模型"思维方式"的迁移而非简单特征复制,并强调合理评估指标和教师模型选择的重要性。最后,作者分享了技术迭代中的边际效应认知,为工业场景下的模型优化提供了实用

企鹅码农的专属播客,分享10多年的实战案例和经验解读,包含YOLO、RT-DETR、AI等各个工作领域。 268

Linux IO多路复用模型

流指的是可以进行I/O操作的内核对象,例如: 文件,管道和套接字等,流的入口就是文件描述符fd。所有对流的读写操作,我们都可以称之为IO操作。当一个流中, 在没有数据read的时候,或者说在流中已经写满了数据,再write,我们的IO操作就会出现一种现象,就是阻塞现象,如下图。综上,我们整理了7中Server的服务器处理结构模型,每个模型都有各自的特点和优势,那么对于多少应付高并发和高CPU利用率的模型,目前多数采用的是模型五(或模型五进程版,如Nginx就是类似模型五进程版的改版)。

m0_53157173的博客 694

Ubuntu开机进入initramfs,解决办法来了!

摘要:Ubuntu系统启动时卡在initramfs界面,表明系统无法正常挂载根文件系统。常见原因包括引导配置错误、文件系统损坏、驱动程序问题和硬件故障。解决方法包括:1)使用fsck修复文件系统;2)通过dmesg排查驱动问题;3)检查硬盘等硬件状态;4)重新安装GRUB引导程序。建议做好系统备份等预防措施,遇到问题时按步骤排查。该问题通常可通过文件系统修复或引导配置重建解决。(148字)

米可的博客! 3421

Linux下的5种I/O模型与3组I/O复用

Python微信订餐小程序课程视频 https://edu.youkuaiyun.com/course/detail/36074 Python实战量化交易理财系统 https://edu.youkuaiyun.com/course/detail/35475 引言 上一篇文章中介绍了一些无缓冲文件I/O函数,但应该什么时机调用这些函数,调用这些I/O函数时进程和内核的行为如何,如何高效率地实现I/O?这篇文章就来谈一谈Linux下的5种I/O模型,以及高性能服务器编程中常用的I/O复用,为后面实现精简版本的高性能服务器做铺垫。 Li

pythonxxoo的博客 593

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Linux(UNIX)五种网络I/O模型与IO多路复用

Linux的内核将所有的外部设备都看做一个文件来操作,对一个文件的读写操作会调用内核提供的系统命令,返回一个file descriptor(fd 文件描述符)。而对一个socket的读写也会有相应的描述符,称为socketfd(socket描述符)。描述符就是一个数字,它指向内核中的一个结构体(文件路径,数据区等一些属性)。 根据UNIX网络编程对I/O模型的分类,UNIX提供了5种I/O模型,分...

小小默:进无止境 2726

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

I/O模型:用select实现多路复用I/O(linux下C语言版)

本文介绍了UNIX/Linux下的I/O多路复用技术,重点讲解了select函数的实现原理和应用。文章首先分析了阻塞I/O、非阻塞I/O等不同I/O模型的优缺点,指出多路复用I/O能有效解决多输入输出流处理问题。详细说明了select函数的使用方法,包括参数设置和辅助功能函数,并通过键盘/鼠标监测和客户端/服务器通信两个示例演示了具体实现。最后总结了select函数的特点:支持多种事件监控但存在文件描述符数量限制,并建议进一步了解poll和epoll等其他多路复用技术。

2301_82019104的博客 1347

Linux 网络I/O模型(阻塞,非阻塞,I/O复用,信号驱动,异步)

文章目录文章搬运用户空间和内核空间进程切换文件描述符buffer IOIO模型阻塞I/O 模型 文章搬运 https://www.toutiao.com/i6708287952520217095/ 用户空间和内核空间 在Linux中不管是内核空间还是用户空间都是使用虚拟地址,在32位平台而言,它的寻址范围是4GB,如下图所示: 所以从较低3GB(0x00000000到0xBFFFFFFF)称之...

Clear Code 666

linux下五种i o的复用模式,Linux中五种常见的I/O模型

一般来说,程序进行输入操作有两步:等、搬迁。在Linux下,共有五种I/O模型,下面就逐一介绍:1>.阻塞I/O(使用比较广)应用程序调用一个I/O函数,如果数据木有准备好,就会导致应用程序阻塞,直到数据准备好了,从内核拷贝到用户空间(进程的缓存),I/O函数返回成功。如一个进程调用recvform,然后系统调用并不返回直到有数据包到达本地系统,然后完成数据拷贝。2>.非阻塞I/O(...

weixin_39623050的博客 195

一文带你深入了解Linux五种I/O模型和I/O多路复用

本文详细介绍了Linux中的五种I/O模型和I/O多路复用技术。主要内容包括: 五种I/O模型:阻塞I/O、非阻塞I/O、信号驱动I/O、I/O多路复用和异步I/O,分析各自特点和区别 阻塞/非阻塞与同步/异步的概念辨析 I/O多路复用的三种实现方式:select、poll和epoll,比较它们的优缺点 epoll的两种触发模式:水平触发(LT)和边缘触发(ET) 惊群问题及其解决方案 常见面试题总结,包括技术选型建议 文章结构清晰,内容全面,适合准备面试或需要深入理解Linux I/O模型的读者。

铭哥不写bug的博客 454

Linux网络I/O复用并发模型

参考:【黑马程序员Redis入门到实战教程,深度透析redis底层原理+redis分布式锁+企业解决方案+黑马点评实战项目】 https://www.bilibili.com/video/BV1cr4y1671t/?

CynthiaXia的博客 1436

深入理解 Linux `select` 模型:I/O 多路复用的基石

Linux系统中的select模型是I/O多路复用的关键技术,通过监控多个文件描述符提高并发处理效率。其原理是使用readfds、writefds和exceptfds三个集合监听I/O事件,当任一文件描述符就绪时通知应用程序。虽然select具有跨平台性和易用性优点,但受限于文件描述符数量(默认1024)和线性遍历效率(O(N)复杂度),不适合大规模并发场景。文中通过TCP回显服务器示例展示了select的实际应用,同时指出在更高并发需求下应选用epoll或kqueue替代方案。(150字)

蜗牛沐雨 1002

【Linux】I/O多路复用模型 select、poll、epoll

在监听 socket 时,需要分配多个线程/进程维护多个 socket 连接,I/O 多路复用技术就是用来使用一个进程来监听维护多个 socket 连接 多路: I/O 状态:可读、可写 复用: 使用一个线程/进程监听处理 I/O 事件,复用多个 socket 请求 一、select 模型 select 原理: 1.创建一个文件描述符集合 fd_set set 0 不监听 1 监听 2.设置文件描述符的状态 FD_ZERO(&set); 初始化监听集合,将位码初始化为 0 FD_SET(int s

努力让自己的能力配得上梦想. 1485

Linux网络编程---I/O复用模型之epoll

Linux网络编程—I/O复用模型之epoll1. epoll模型简介epoll是Linux多路服用IO接口select/poll的加强版,e对应的英文单词就是enhancement,中文翻译为增强,加强,提高,充实的意思。所以epoll模型会显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。 epoll把用户关心的文件描述符上的时间放在内核的一个事件表中,无需像select和po

men_wen的博客 1万+

【Linux开发】I/O 复用:poll 模型

无描述符上限:只受系统内存限制,可通过ulimit -n调整。数据结构清晰events和revents分离,不需要每次重新构造。跨平台:几乎所有 UNIX 系统(包括 Linux、BSD、macOS)都支持,Windows 也有WSAPoll(功能类似)。编程简单:比select稍好,比epoll简单。poll是select的改进版,它去掉了描述符上限,使用数组管理,避免了fd_set的大小限制。但仍需遍历所有 fd,在大量连接但少数活跃时效率不如epoll。

yy_xzz的博客 417

Linux系统的I/O模型,多路复用IO实现并发。

多为我自己的个人理解,希望不要误导。。。。。。。。。。 前端时间做了一个基于web服务器的在线商城的项目的练习,其中运用到了TCP的并发服务器(多个客户端同时访问一个服务器),经过查阅相关资料。现将linux系统中的I/O模型总结如下。期间可能有总结的不到位的地方,后期会随着学习的深入,不断改进。 在讲述IO模型前,先来提一提同步和异步的概念,就我个人的简单理解。 同步:一段代码中,我发给对方一个通知,我等待对方回复我,对方回复我了,...

m0_57781632的博客 404

Linux五大网络模型之I/O多路复用浅入深出

网上寻得一篇讲解Linux I/O模型很好的文章,特此引用。 文章摘录自:https://new.qq.com/rain/a/20210610A05G9600 浅入深出的解释 清·俞樾《湖楼笔谈》六:“盖诗人用意之妙,在乎深入显出。入之不深,则有浅易之病;出之不显,则有艰涩之患。” 从出处可知,“入”说的是内容,“出”说的是表达,内容在文字之下,文字驾驭内容,是上下结构的深入浅出! 如果把一篇技...

翎野君的博客 556
上一篇: Linux socket 高级主题
下一篇: c++ 语言技巧之traits
WeinKee
博客等级 码龄15年 3粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值