IO复用模式--select、poll、epoll详解

     IO模式,从大类上可以分为同步IO和异步IO,同步和异步的区别主要是针对IO事件的执行者,拿读数据来说,异步IO是内核等待内核缓存区数据就绪,然后由内核负责将数据拷贝到用户空间缓冲区,再发送实现完成信号,而同步IO是发送内核缓冲区数据就绪信号,将数据copy到用户缓冲区还是由应用程序进行io系统调用实现。同步IO又包括阻塞IO、非阻塞IO、IO多路复用和信号IO模式。其中,IO复用是现在实现高性能网络服务器的常用手段,可以用其代替一连接-一线程的服务器编程模式。

    在Linux 内核2.6之前,采用select和poll方式来实现IO复用,在2.6引入了高性能的epoll实现方式。另外,Java NIO的实现底层也是基于epoll的,高性能的服务器网络编程框架/NIO框架netty、mina也是在nio的基础上做了进一步的包装,解决了Java NIO诸如epoll bug空轮询等bug,netty等高性能网络框架也一般作为网络服务器、RPC、hadoop的底层通信框架。为了更好的理解,下边对select、poll和epoll做一些基本学习。

IO复用模式

当用户调用select时,会阻塞在select调用上,同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。
所以,I/O 多路复用的特点是通过一种机制一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select()函数就可以返回。

这个图和blocking IO的图其实并没有太大的不同,事实上,还更差一些。因为这里需要使用两个system call (select 和 recvfrom),而blocking IO只调用了一个system call (recvfrom)。但是,用select的优势在于它可以同时处理多个connection。

所以,如果处理的连接数不是很高的话,使用select/epoll的web server不一定比使用multi-threading + blocking IO的web server性能更好,可能延迟还更大。select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。)

在IO multiplexing Model中,实际中,对于每一个socket,一般都设置成为non-blocking,但是,如上图所示,整个用户的process其实是一直被block的。只不过process是被select这个函数block,而不是被socket IO给block

select,poll,epoll都是IO多路复用的机制。I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的

select、poll实现

select函数为:
int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
select 函数监视的文件描述符分3类,分别是writefds、readfds、和exceptfds。调用后select函数会阻塞,直到有描述副就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以 通过遍历fdset,来找到就绪的描述符。
    select的一 个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但 是这样也会造成效率的降低。要注意:select的maxfd=监听的最大fd+1。注意,select可以监听的文件描述符fd为1024,并不是指它支持的并发量只能在1024以下,这里的1024是指某一时刻同时监听的个数,当处理完socket读写时间后,会关闭其fd,然后加入新的监听fd。
  poll的机制与select类似,与select在本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数量的限制。
int poll (struct pollfd *fds, unsigned int nfds, int timeout);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值