1.select:
select本质上是通过设置或者检查存放fd标志位的数据结构数据结构来进行下一步的处理,时间复杂度:O(n)
缺点:
1)、每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大;
2)、同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大;
3)、单个进程可监视的fd数量被限制;
4)、对socket进行扫描是线性扫描;
优点:
1)、select的可移植性更好,在某些Unix系统上不支持poll()。
2)、select对于超时值提供了更好的精度:微秒,而poll是毫秒。
2.poll:
poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待对垒中加入一项继续遍历,如果遍历完所有fd后没有发现就绪设备,则挂起当前进程,知道设备就绪或者主动超时,被唤醒后它又要再次遍历fd这个过程经理了多次无谓的遍历。时间复杂度O(n)
缺点:
1)、大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义;
2)、与select一样,poll返回后,需要轮询pollfd来获取就绪的描述符。
优点:
1)、poll() 不要求开发者计算最大文件描述符加一的大小。
2)、poll() 在应付大数目的文件描述符的时候速度更快,相比于select。
3)、它没有最大连接数的限制,原因是它是基于链表来存储的。
3.epoll:
epoll可以理解为event poll,不同于忙轮询和无差别轮询,epoll会把哪个流发生了怎样的I/O事件通知我们。所以我们说epoll实际上是事件驱动(每个事件关联上fd)的,此时我们对这些流的操作都是有意义的。(复杂度降低到了O(1))
缺点:
1)、相对select来说, epoll的跨平台性不够用 只能工作在linux下, 而select可以在windows linux apple上使用。
2)、相对select来说 还是用起来还是复杂了一些, 不过和IOCP比起来 增加了一点点的复杂度却基本上达到了IOCP的并发量和性能, 而复杂度远远小于IOCP
3)、 相对IOCP来说 对多核/多线程的支持不够好, 性能也因此在性能要求比较苛刻的情况下不如IOCP.
优点:
1)、IO效率不随FD数目增加而线性下降:epoll不存在这个问题,它只会对"活跃"的socket进行操作
2)、使用mmap加速内核与用户空间的消息传递:epoll通过内核和用户空间共享一块内存来实现的。