Linux网络IO模型
同步和异步,阻塞和非阻塞
Linux下的五种IO模型
同步和异步,阻塞和非阻塞
Linux 下的五种I/O模型:
阻塞IO(Blocking IO) BIO
非阻塞IO(No Blocking IO)
IO复用(select 、poll和epoll) NIO
信号驱动IO (signal driven IO)
异步IO(asynchronous IO) AIO
select
对一个socket,两次调用,两次返回,比阻塞IO并没有什么优越性;关键是能实现同时对多个socket进行处理。
阻塞IO模型
I/O 复用模型
IO 复用需要使用两个系统调用(select 和 recvfrom),而 blocking IO 只
调用了一个系统调用(recvfrom)。但是,用 select 的优势在于它可以同时处理多个 connection。
所以,如果处理的连接数不是很高的话,使用 select/epoll 的 web server 不一定比使用
multi-threading + blocking IO 的 web server 性能更好,可能延迟还更大。select/epoll 的优势
并不是对于单个连接能处理得更快,而是在于能处理更多的连接。
NIO对于BIO来说,有select多路复用器,能接收更多请求
从Linux代码结构看网络通信模式
Linux 下的 IO 复用编程
select,poll,epoll 都是 IO 多路复用的机制。I/O 多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但 select,poll,epoll 本质上都是同步 I/O,因为他们都需要在读写事件就绪后自己负责进行读写,并等待读写完成。
select 、poll、epoll比较
select、poll、epoll都是操作系统实现IO多路复用的机制
支持一个进程所能打开的最大连接数
模式 | |
---|---|
select | 单个进程所能打开的最大连接数有 FD_SETSIZE 宏定义,其大小是 32个整数的大小(在 32 位的机器上,大小就是 3232,同理 64 位机器上FD_SETSIZE 为 3264),当然我们可以对进行修改,然后重新编译内核,但是性能可能会受到影响。 |
poll | poll 本质上和 select 没有区别,但是它没有最大连接数的限制,原因是它是基于链表来存储的 |
epoll | 虽然连接数基本上只受限于机器的内存大小 |
FD 剧增后带来的 IO 效率问题
模式 | |
---|---|
select | 因为每次调用时都会对连接进行线性遍历,所以随着 FD 的增加会造成遍历速度慢的“线性下降性能问题”。 |
poll | 同上 |
epoll | 因为 epoll 内核中实现是根据每个 fd 上的 callback 函数来实现的,只有活跃的 socket 才会主动调用 callback,所以在活跃 socket 较少的情况下,使用 epoll 没有前面两者的线性下降的性能问题,但是所有 socket 都很活跃的情况下,可能会有性能问题。 |
消息传递方式
模式 | |
---|---|
select | 内核需要将消息传递到用户空间,都需要内核拷贝动作 |
poll | 同上 |
epoll | epoll 通过内核和用户空间共享一块内存来实现的。 |
综上,在选择 select,poll,epoll 时要根据具体的使用场合以及这三种方式的自身特点。
1、表面上看 epoll 的性能最好,但是在连接数少并且连接都十分活跃的情况下,select和 poll 的性能可能比 epoll 好,毕竟 epoll 的通知机制需要很多函数回调。
2、select 低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善。