这么回答offer拿到手软,谈谈你对IO多路复用机制的理解

简介: 一位工作5年的小伙伴面试时被问到IO相关的问题,说,谈谈你对IO多路复用机制的理解。当时他说只是听过多路复用,具体细节没有了解过。今天,我给大家分享一下我的理解。

一位工作5年的小伙伴面试时被问到IO相关的问题,说,谈谈你对IO多路复用机制的理解。当时他说只是听过多路复用,具体细节没有了解过。今天,我给大家分享一下我的理解。

1 IO多路复用

fc45f6948ac21a96e6560227fe6e081e.jpg

IO多路复用是一种同步的IO模型。利用IO多路复用模型,可以实现一个线程监视多个文件句柄;一旦某个文件句柄就绪,就能够通知到对应应用程序进行相应的读写操作;没有文件句柄就绪时就会阻塞应用程序,从而释放出CPU资源。

f8b85604ba7a0c1ca059e2791bcee921.jpg

IO可以理解为,在操作系统中,数据在内核态和用户态之间的读、写操作,大部分情况下是指网络IO;

7ef05776dbe32323fb98d360eaee5abe.jpg

多路大部分情况下是指多个TCP连接,也就是多个Socket 或者多个Channel;

2ce5b2332e9e2dca3b865f191690e1f7.jpg

复用是指复用一个或多个线程资源。IO多路复用意思就是说,一个或多个线程处理多个 TCP 连接。尽可能地减少系统开销,无需创建和维护过多的进程/线程。

d6e1f6a1415c638e8ff0e120c20bb64e.jpg

实现IO多路复用的模型有三种,分别是Select、poll 和 epoll。下面详细介绍一下三种多路复用模型的基本原理和优缺点:

2 select模型

6596f5585ec324e1bb3bade2a11c5e0e.jpg

select模型,它的基本原理是,采用轮询和遍历的方式。也就是说,在客户端操作服务器时,会创建三种文件描述符,简称FD。分别是writefds(写描述符)、readfds(读描述符)和 exceptfds(异常描述符)。

a6e46dbf5b1afe2aecd99c412cfc39aa.jpg

而select会阻塞监视这三种文件描述符,等有数据、可读、可写、出异常或超时都会返回;

4091cf7212b3efbb5a7c17efcd4eb150.jpg

返回后通过遍历fdset,也就是文件描述符的集合,来找到就绪的FD,然后,触发相应的IO操作。

39437867945067b4b2dd631347cf9b6a.jpg

它的优点是跨平台支持性好,几乎在所有的平台上支持。

e250aeaa308c38724f9dcc7d6bcb6bb9.jpg

它的缺点也很明显,由于select是采用轮询的方式进行全盘扫描,因此,随着FD数量增多而导致性能下降。

1f90eca62a5e7ddf0288c7c081047ca5.jpg

因此,每次调用select()方法,都需要把FD集合从用户态拷贝到内核态,并进行遍历。而操作系统对单个进程打开的FD数量是有限制的,一般默认是1024个。虽然,可以通过操作系统的宏定义FD_SETSIZE修改最大FD数量限制,但是,在IO吞吐量巨大的情况下,效率提升仍然有限。

3 poll模型

4b62b670cb0be826cae3f34ef9f5cb6d.jpg

poll 模型的原理与select模型基本一致,也是采用轮询加遍历,唯一的区别就是 poll 采用链表的方式来存储FD。


所以,它的优点点是没有最大FD的数量限制。

43c6a2db0a757299c0948ebe6057f846.jpg

它的缺点和select一样,也是采用轮询方式全盘扫描,同样也会随着FD数量增多而导致性能下降。

a711f553a0f47dfb47ee3a5f9e6604e4.jpg

4 epoll模型

由于select和poll都会因为吞吐量增加而导致性能下降,因此,才出现了epoll模型。


epoll模型是采用时间通知机制来触发相关的IO操作。它没有FD个数限制,而且从用户态拷贝到内核态只需要一次。它主要通过系统底层的函数来注册、激活FD,从而触发相关的 IO 操作,这样大大提高了性能。主要是通过调用以下三个系统函数:

224f9d1a0c4988e0a71c492a418fc261.jpg

1、epoll_create()函数,在系统启动时,会在Linux内核里面申请一个B+树结构的文件系统,然后,返回epoll对象,也是一个FD。

7273a723f07d16ad750a36c683a779f9.jpg

2、epoll_ctl()函数,每新建一个连接的时候,会同步更新epoll对象中的FD,并且绑定一个 callback回调函数。

fa6b1759ca360085290622f46e4a8378.jpg

3、epoll_wait()函数,轮询所有的callback集合,并触发对应的 IO 操作

cff51bbff4f76b3925f3b16618a53c52.jpg

所以,epoll模型最大的优点是将轮询改成了回调,大大提高了CPU执行效率,也不会随FD数量的增加而导致效率下降。当然,它也没有FD数量限制,也就是说,它能支持的FD上限是操作系统的最大文件句柄数。一般而言,1G 内存大概支持 10 万个句柄。分布式系统中常用的组件如Redis、Nginx都是优先采用epoll模型。

8f5eb503a2b052c64c65b14b1bc1c1f7.jpg

它的缺点是只能在Linux下工作。

5 综合对比

下表是三种多路复用模型的综合对比,有兴趣的小伙伴可以截图保存一下,或者到我的个人煮叶简介中获取。

b581e6bea8f0c9a52decab75d8cefe1f.jpg

好了,以上就是我对IO多路复用机制的理解。


我是被编程耽误的文艺Tom,关注我,面试不再难!

3c2047b0ee454886b4e6edf75f6c98c3.gif

相关文章
|
2月前
|
网络协议 安全 Linux
Linux C/C++之IO多路复用(select)
这篇文章主要介绍了TCP的三次握手和四次挥手过程,TCP与UDP的区别,以及如何使用select函数实现IO多路复用,包括服务器监听多个客户端连接和简单聊天室场景的应用示例。
98 0
|
2月前
|
存储 Linux C语言
Linux C/C++之IO多路复用(aio)
这篇文章介绍了Linux中IO多路复用技术epoll和异步IO技术aio的区别、执行过程、编程模型以及具体的编程实现方式。
106 1
Linux C/C++之IO多路复用(aio)
|
2月前
|
Linux C++
Linux C/C++之IO多路复用(poll,epoll)
这篇文章详细介绍了Linux下C/C++编程中IO多路复用的两种机制:poll和epoll,包括它们的比较、编程模型、函数原型以及如何使用这些机制实现服务器端和客户端之间的多个连接。
36 0
Linux C/C++之IO多路复用(poll,epoll)
|
2月前
|
Java Linux
【网络】高并发场景处理:线程池和IO多路复用
【网络】高并发场景处理:线程池和IO多路复用
58 2
|
2月前
|
监控 网络协议 Java
IO 多路复用? 什么是 IO 多路复用? 简单示例(日常生活)来解释 IO 多路复用 一看就懂! 大白话,可爱式(傻瓜式)教学! 保你懂!
本文通过日常生活中的简单示例解释了IO多路复用的概念,即一个线程通过监控多个socket来处理多个客户端请求,提高了效率,同时介绍了Linux系统中的select、poll和epoll三种IO多路复用的API。
154 2
|
3月前
|
消息中间件 NoSQL Java
面试官:谈谈你对IO多路复用的理解?
面试官:谈谈你对IO多路复用的理解?
55 0
面试官:谈谈你对IO多路复用的理解?
|
3月前
|
网络协议 Java Linux
高并发编程必备知识IO多路复用技术select,poll讲解
高并发编程必备知识IO多路复用技术select,poll讲解
|
5月前
|
缓存 网络协议 算法
【Linux系统编程】深入剖析:四大IO模型机制与应用(阻塞、非阻塞、多路复用、信号驱动IO 全解读)
在Linux环境下,主要存在四种IO模型,它们分别是阻塞IO(Blocking IO)、非阻塞IO(Non-blocking IO)、IO多路复用(I/O Multiplexing)和异步IO(Asynchronous IO)。下面我将逐一介绍这些模型的定义:
265 2
|
5月前
|
存储 Java Unix
(八)Java网络编程之IO模型篇-内核Select、Poll、Epoll多路复用函数源码深度历险!
select/poll、epoll这些词汇相信诸位都不陌生,因为在Redis/Nginx/Netty等一些高性能技术栈的底层原理中,大家应该都见过它们的身影,接下来重点讲解这块内容。
|
6月前
|
Linux C++
c++高级篇(三) ——Linux下IO多路复用之poll模型
c++高级篇(三) ——Linux下IO多路复用之poll模型