IO多路复用技术详解

  IO多路复用:I/O是指网络I/O,多路指多个TCP链接(即socket或者channel),复用指复用一个或几个线程。意思说一个或一组线程处理多个TCP链接。最大优点是减小系统开销小,没必要建立过多的进程/线程,也没必要维护这些进程/线程。
  IO多路复用使用两个系统调用(select/poll/epoll和recvfrom),blocking IO只调用了recvfrom;select/poll/epoll 核心是能够同时处理多个connection,而不是更快,因此链接数不高的话,性能不必定比多线程+阻塞IO好,多路复用模型中,每个socket,设置为non-blocking,阻塞是被select这个函数block,而不是被socket阻塞的。数组

select机制
基本原理:
  客户端操做服务器时就会产生这三种文件描述符(简称fd):writefds(写)、readfds(读)、和exceptfds(异常)。select会阻塞住监视3类文件描述符,等有数据、可读、可写、出异常 或超时、就会返回;返回后经过遍历fdset整个数组来找到就绪的描述符fd,而后进行对应的IO操做。
优势:
  几乎在全部的平台上支持,跨平台支持性好
缺点:
  因为是采用轮询方式全盘扫描,会随着文件描述符FD数量增多而性能降低。
  每次调用 select(),须要把 fd 集合从用户态拷贝到内核态,并进行遍历(消息传递都是从内核到用户空间)
  默认单个进程打开的FD有限制是1024个,可修改宏定义,可是效率仍然慢。服务器

poll机制:
  基本原理与select一致,也是轮询+遍历;惟一的区别就是poll没有最大文件描述符限制(使用链表的方式存储fd)。
epoll机制:
基本原理:
  没有fd个数限制,用户态拷贝到内核态只须要一次,使用时间通知机制来触发。经过epoll_ctl注册fd,一旦fd就绪就会经过callback回调机制来激活对应fd,进行相关的io操做。
epoll之因此高性能是得益于它的三个函数
  1)epoll_create()系统启动时,在Linux内核里面申请一个B+树结构文件系统,返回epoll对象,也是一个fd
  2)epoll_ctl() 每新建一个链接,都经过该函数操做epoll对象,在这个对象里面修改添加删除对应的连接fd, 绑定一个callback函数
  3)epoll_wait() 轮训全部的callback集合,并完成对应的IO操做
优势:
  没fd这个限制,所支持的FD上限是操做系统的最大文件句柄数,1G内存大概支持10万个句柄
  效率提升,使用回调通知而不是轮询的方式,不会随着FD数目的增长效率降低
  内核和用户空间mmap同一块内存实现(mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间)网络

例子:100万个链接,里面有1万个链接是活跃,咱们能够对比 select、poll、epoll 的性能表现
  select:不修改宏定义默认是1024,l则须要100w/1024=977个进程才能够支持 100万链接,会使得CPU性能特别的差。
  poll:    没有最大文件描述符限制,100万个连接则须要100w个fd,遍历都响应不过来了,还有空间的拷贝消耗大量的资源。
  epoll:    请求进来时就建立fd并绑定一个callback,主须要遍历1w个活跃链接的callback便可,即高效又不用内存拷贝。多线程