阻塞I/O、非阻塞I/O和I/O多路复用

看概念:阻塞I/O、非阻塞I/O和I/O多路复用 - skiler - 博客园

图解阻塞io和非阻塞io及多路复用机制 - 左耳听风的博客 - CSDN博客

主要看看这篇:IO模式和IO多路复用(阻塞IO、非阻塞IO、同步IO、异步IO等概念) - qq_34802511的博客 - CSDN博客

1、三种概念

1)阻塞I/O

进程发起read后,如果kernel未准备好数据,进程就会被block,进入等待阶段;

等待kernel将数据准备好,才会返回数据,解除阻塞;

阻塞I/O


2)非阻塞I/O

进程发起read请求,kernel未准备好数据,直接返回一个error,进程无需阻塞等待;

进程会轮询发送read请求,如此往复;

一直到kernel准备好数据,才把数据拷贝并返回给进程,结束轮询;

非阻塞I/O


3)I/O多路复用

进程调用select/poll/epoll,select/poll/epoll会将进程block起来;

kernel会‘监视’所有select负责的socket;

当任何一个socket准备好数据,select就会返回(也就是图中的return medable);

进程调用read(图中第二次 system call),将数据从kernel拷贝到用户进程;

总结:所以,I/O 多路复用的特点是通过一种机制一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select()函数就可以返回


I/O多路复用

2、I/O多路复用的特点及合理使用场景

从图中可以明显看到,I/O多路复用和阻塞I/O差别其实不大,事实上,还更差一些。因为这里需要使用两个system call (select 和 recvfrom),而blocking IO只调用了一个system call (recvfrom)。

但是,I/O多路复用的优势是:同时处理多个连接请求

所以,如果处理的连接数不是很高的话,使用select/epoll的web server不一定比使用多线程 + 阻塞 IO的web server性能更好,可能延迟还更大。

select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。

3、I/O多路复用主要的三种实现方式:

select, poll, epoll 都是I/O多路复用的具体的实现,之所以有这三个鬼存在,其实是他们出现是有先后顺序的。

1)select

不是线程安全;只返回数据,不会告知是哪个sock返回的,只能自己遍历去查找;只能监视1024个链接;

2)poll

相对于select改进了:可监视无数个链接

缺点:仍旧不是线程安全。

3)epoll

改进:线程安全

缺点:只有linux支持

ngnix 的设计原则里面, 它会使用目标平台上面最高效的I/O多路复用模型咯,所以才会有这个设置。一般情况下,如果可能的话,尽量都用epoll吧。

以上都是针对高并发大流量而言,如果不是,其实用哪个都差不多。

你可能感兴趣的:(阻塞I/O、非阻塞I/O和I/O多路复用)