与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程
,也不必维护这些进程/线程,从而大大减小了系统的开销
I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作
。但select,pselect,poll,epoll本质上都是同步阻塞型
,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间
IO多路复用可以分为三种:
1、select
各个系统对select支持的很好,进程最多可以监视的文件描述数量为:1024(32位机器默认),使用FD_SETSIZE可以设置该数目
设计到数据的拷贝,另外还采用轮询的方式扫描,所以效率较低
2、poll
poll本质上和select没有区别,它也是将用户传入的数组拷贝到内核空间,它是基于链表来存储的,所以
它没有最大连接数的限制
它也是用轮询的方式遍历所有文件描述符
3、epoll
没有最大连接数目限制,直接使用内存映射,不涉及到数据拷贝
不是采用轮询的方式,epoll使用“事件”的就绪通知方式
,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd
,epoll_wait便可以收到通知,所以当活跃的文件描述符较少时效率很高
是Linux所特有
epoll对文件描述符操作可以分为两种:LT(level trigger)、ET(edge trigger),LT为默认模式
LT(level triggered)是缺省的工作方式,并且同时支持block和no-block socket,如果你不作任何操作,内核还是会继续通知你的
ET(edge-triggered)是高速工作方式,只支持no-block socket,如果一直不对这个fd作IO操作(从而导致它再次变成未就绪),内核不会发送更多的通知(only once)
本文大部分都是借鉴的:https://www.jianshu.com/p/dfd940e7fca2