首页 > 系统相关 >Linux面试题2:网络IO模型 & IO多路复用

Linux面试题2:网络IO模型 & IO多路复用

时间:2022-11-26 17:37:45浏览次数:55  
标签:面试题 set epoll int fd IO Linux select

网络IO

先确定一下范围,我们讨论的都是网络IO,现阶段计算机早已经从CPU密集型转换成网络IO密集型,所以网络io的类型对于服务响应而言更重要。

五种IO模型

依据Unix的IO分类,网络IO分为五类

  • 阻塞IO(BlockingIO
  • 非阻塞IO(Non-Blocking IO
  • IO多路复用( IO Multiplexing
  • 信号驱动IO(signal driven IO
  • 异步IO(async IO

内核态和用户态

可见另一篇文章

网络IO的两阶段阶段

  1. 等待网卡读就绪 —> 将网卡数据复制奥内核缓冲区
  2. 将内核缓冲区的数据复制到用户空间

其中:第一阶段主要用来区分是否是阻塞IO

阻塞与非阻塞

进行一个IO操作之后,无论是否有数据、是否就绪,是否会立刻返回而不阻塞用户进程的逻辑。
当用户进程发出read操作时,如果kernel中的数据没有准备好,不会block用户进程,而是返回一个EAGAIN err。从用户的角度而言,发起一个读操作,不需要等待,马上得到了一个结果。
一旦kernel的数据准备好了,收到用户进程的一个systemcall,就会马上把数据拷贝到用户内存,然后返回。

同步与异步

第二阶段,内核将数据拷贝到用户空间是否是同步进行的,决定是否是异步IO;除了aync IO以外其他都是同步的IO模型。

面试回答

概述

IO多路复用实际就是select/poll/epoll这些多路选择器,使用一个线程同时监听多个文件描述符(fd_set), I/O事件,阻塞等待并且在某个文件描述符可读写时收到通知。linux在处理网络IO连接时的优化,复用的不是I/O连接,而是复用的是线程,让一个线程处理多个连接。

select/poll/epoll

选择器 运行逻辑 特点 缺点
select 1.最大并发数限制; 2.每次调用select,需要把fd_set集合拷贝到内核态;3.性能衰减严重
poll poll与select类似,只是没有最大并发数限制
epoll

select

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
 
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
 
// 和 select 紧密结合的四个宏:
void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);

运行逻辑
fd_set如果是1 字节byte, 1byte = 8bit,每一个bit可以表示一个文件描述符fd,则1byte的fd_set最大可以对应8个fd

  1. 执行 FD_ZERO(&set), 则 set 用位表示是 0000,0000
  2. 若 fd=5, 执行 FD_SET(fd, &set); 后 set 变为 0001,0000(第 5 位置 为 1)
  3. 再加入 fd=2, fd=1,则 set 变为 0001,0011
  4. 执行 select(6, &set, 0, 0, 0) 阻塞等待
  5. 若 fd=1, fd=2 上都发生可读事件,则 select 返回,此时 set 变为 0000,0011 (注意:没有事件发生的 fd=5 被清空)

特点

  1. 可以监控的文件描述符个数取决于 sizeof(fd_set)的值。如果 sizeof(fd_set) = 512, 每个bit表示一个文件描述符, 512 * 8 = 4096。
  2. 需要拷贝 fd_set,转换成一个array
  3. 需要循环fd_set,线性扫描整个fd_set

epoll

epoll是Linux Kernel 2.6之后引入的IO事件驱动技术,本质上还是一个线程处理所有链接的等待消息准备好IO事件。但是 当数十万的并发连接存在时,可能每一毫秒猪油数百个活跃的链接,同时其余数十万连接在这一毫秒是非活跃的,而select&poll的使用方法是 返回的活跃链接 == select(全部带监控的连接)

高频调用的接口是select()方法,而这个方法任何轻微的效率损失都会被高频两个字放大。epoll解决了这个问题.

#include <sys/epoll.h>  
int epoll_create(int size); // int epoll_create1(int flags);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

epoll的工作原理如下图:

  • epoll_ctl 来插入和删除一个fd,实现从用户态到内核态的拷贝,确保每一个fd只在生命周期一次拷贝。
  • epoll使用红黑树存储所有监控的fd,红黑树的时间复杂度O(logN)。
  • 每一个fd有一个关键步骤:fd回合相应的设备(网卡、硬盘)驱动程序建立一个回调关系,在fd相应的时间出发之后,内核就会调用这个回调函数,ep_poll_callback,这个回调函数会把fd添加到fdllist的双向链表(就绪列表之中)epoll_wait这个就是检查是否有就绪的fd,所以非常高效。

Reactor网络模型

Linux平台主流的高性能网络库/框架中,大都采用了Reactor模式,比如netty、libevent等。

Reactor模式本质上是指 IO多路复用 + 非阻塞IO的模式。

通常是: 一个主线程负责做event-loop时间循环和IO读写,通过select/poll/epoll_wait等系统调用监听IO事件,业务逻辑提交给其他工作线程去做。
非阻塞IO核心思想是避免阻塞在read()或者write()或者其他IO系统调用上,这样可以最大限度的服用event-loop线程,让一个线程能服务多个sockets。

Reactor模式的基本工作流程如下:

  1. Server端完成在bind&Listen之后,

标签:面试题,set,epoll,int,fd,IO,Linux,select
From: https://www.cnblogs.com/fenngz/p/16926621.html

相关文章

  • linux重置core文件生成目录
    查看/proc/sys/kernel/core_pattern文件或kernel.core_pattern里面的内容默认是core,也就是core文件的生成路径和工作路径一致,如果内容为其他值,那么对应的core文件就会生成......
  • Introduction to Computer Science #Homework 06
    IntroductiontoComputerScienceHomework061.程序是如何执行的3.2.1给寄存器R赋值20CPU将寄存器R中的值存回a所在的地址3.2.2将主存中1200地址处的值读取到寄......
  • # Introduction to Computer Science #Homework 05
    IntroductiontoComputerScienceHomework051.关于期末大作业团队成员李纪远/席萱赫/祖家琪/刘立威游戏想法游戏名:西风哗哗?大赢家!游戏类型:大富翁like棋......
  • 腾讯会议如何在Linux下的安装与使用
    腾讯会议官网https://meeting.tencent.com/download?mfrom=OfficialIndex_TopBanner1_Download下载腾讯会议官网只提供了deb版的安装包,但这并不影响在非debian下使用!......
  • javascript面试题
    1.null和undefined区别首先Undefined和Null都是基本数据类型,这两个基本数据类型分别都只有一个值,就是undefined和null。undefined代表的含义是未定义,null代表......
  • Linux系列---【linux服务器监控和浏览器客户端连接工具-Cockpit】
    linux服务器监控和浏览器客户端连接工具-Cockpit1.Cockpit的用途(1)Cockpit是一个免费且开源的基于web的Linux服务器管理工具。并且在CentOS8和RHEL8中,Cockpit更......
  • linux配置开启KASAN功能
    【KASANlinux内存检测工具】 (本文档将引导编译一个开启kasan功能的内核)一简介: KernelAddressSanitizer缩写KASAN;是linux内核的动态内存检测工具, 主要检查......
  • java——JDBC——JDBC各个类详解——Connection
      2.Connection:数据库连接对象1.功能:1.获取执行sql的对象*StatementcreateStatement()......
  • Linux 卸载磁盘target is busy
    一、简介问题:umount/dev/sdxx命令时可能会报"deviceisbusy",这个合理的报错可以防止正在使用的设备上的数据丢失。如1)使用者自己清楚确实发生了错误2)使用者不在乎数据......
  • [Bug0061] RabbitMQ 报错 An unexpected connection driver error occured
    问题Java项目连接RabbitMQ报错Anunexpectedconnectiondrivererroroccured场景集成RabbitMQ的开源项目启动报错原因yml中端口配置错误,也是小白很容易犯错之一,配......