各种IO

IO多路复用select,poll,epoll详解

2018-07-12  本文已影响46人  Catcher07

I/O复用模型
多路复用是指使用一个线程来检查多个文件描述符(Socket)的就绪状态,比如调用select和poll函数,传入多个文件描述符(FileDescription,简称FD),如果有一个文件描述符(FileDescription)就绪,则返回,否则阻塞直到超时。得到就绪状态后进行真正的操作可以在同一个线程里执行,也可以启动线程执行(比如使用线程池)。

目前支持IO多路复用的系统调用有select,pselect,poll,epoll。IO多路复用是一种机制,一个进程监控多个描述符,一旦某个描述符准备就绪(一般是读就绪或者写就绪),通知应用进行相应的IO操作(读写)。但是select、pselect、poll、epoll本质上都是同步IO,它们都是要在读写事件就绪后自己负责读写,也就是说这个读写过程是阻塞的。而异步IO是无需自己负责读写,把所有的操作全部给内核来处理。系统内核负责把数据从内核复制到用户空间,在这个过程中,进程全程没有阻塞。

image.png image.png

与多进程和线程的技术相比,I/O多路复用技术最大的优势就是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。

一、使用场景

IO多路复用指的是内核一旦发现一个或者多个IO条件准备读取,就通知该进程。IO多路复用适用如下场合。

二、select、poll、epoll简介

epoll跟select都能提供多路IO复用的解决方案。在现在的Linux内核里有都能够支持,其中epoll是Linux特有的,而select是POSIX所规定,一般操作系统均有实现。

1. select

基本原理:select函数监视的文件描述符分为3类,分别为write_fds、read_fds、except_fds。调用select函数后,进程会阻塞,直到描述符就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以通过遍历fd_set,来找到就绪的描述符。

2. poll

select() 和 poll() 系统调用的本质一样,poll() 的机制与 select() 类似,与 select() 在本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是 poll() 没有最大文件描述符数量的限制(但是数量过大后性能也是会下降)。poll() 和 select() 同样存在一个缺点就是,包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,它的开销随着文件描述符数量的增加而线性增大。

注意:select和poll都需要在返回后,通过遍历文件描述符来获取已经就绪的文件描述符。如果只有很少的文件描述符处于就绪状态,那么随着监视的描述符数量的增长,其效率也会线性下降。

3.epoll

epoll是在2.6内核中提出的,是之前的select和poll的增强版本。相对于select和poll来说,epoll更加灵活,没有描述符限制。epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。

epoll的优点:

只有活跃可用的FD才会调用callback函数;即epoll最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,epoll的效率就会远远高于select和poll。

epoll的操作模式

epoll对文件描述符的操作有两种模式:LT(level trigger)和ET(edge trigger)。LT模式是默认模式,LT模式与ET模式的区别如下:

4.select、poll、epoll

在select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,而epoll事件先通过epoll_ctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait()时便得到通知。(此处去掉了遍历文件描述符,而是通过监听回调的的机制。这正是epoll的魅力所在。)

三、select、poll、epoll区别

四、面试可回答区别

select

poll

epoll

参考自

https://www.cnblogs.com/jeakeven/p/5435916.html
https://www.nowcoder.com/questionTerminal/c162e1e930a34ea3ad6c8863ccff0fa2
https://blog.csdn.net/y396397735/article/details/55004775
https://www.cnblogs.com/ccsccs/articles/4224253.html (重点分析select)
https://blog.csdn.net/apacat/article/details/51375950 (这个也比较详细)
https://blog.csdn.net/yusiguyuan/article/details/15027821
https://blog.csdn.net/mmz_xiaokong/article/details/8704988
https://www.cnblogs.com/Anker/p/3265058.html (区别整理)
https://blog.csdn.net/men_wen/article/details/53456491 (最好的例子)
https://www.cnblogs.com/zhuwbox/p/4221934.html
https://blog.csdn.net/tennysonsky/article/details/45745887/ (配合了代码的分析)

上一篇下一篇

猜你喜欢

热点阅读