三种I/O复用的比较

来源:互联网 发布:会计软件的合法性 编辑:程序博客网 时间:2024/05/02 02:52

相同点:

1.select、poll、epoll这三组I/O复用系统调用都能同时监听多个文件描述符,
2。他们都通过timeout参数指定要等待的时间。直到事件就绪时返回
3.返回值就是就绪的文件描述符的数量。

不同点:

epoll高效的原因:

1>、底层采用回调机制激活某个节点,将已经就绪的文件描述符添加到就绪队列中去;

2>、当有新的事件发生的时候,该结点会被插入到epoll模型中的红黑树中去,红黑树增删查改效率比较高,它的时间复杂度为O(N*lgN);

3>、epoll_wait获得就绪的文件描述符是从就绪队列中获得的,它的时间复杂度为O(1),这也是epoll的时间复杂度同时也是epoll高效的原因;

4>、epoll所关心的文件描述符是无上限的;

5>、将就绪队列中的数据结点映射到epoll_wait的events结构体中,节省了一次内核态至用户态的拷贝,这是mmap技术(内存映射技术);

6>、就绪事件的陈列方式不同,epoll访问的是就绪队列避免了访问无价值的数据,而select是访问的是一个数组;

7>.epoll有两种工作模式:ET和LT模式,可以避免阻塞带来的性能影响

另外:

select的参数没有将文件描述符和事件绑定,他仅仅是一个文件描述符的集合(表示是否),所以select需要分别用三个参数来区分传入的可读,可写及异常事件,这不仅限制了select只能处理这三种事件,另外由于内核对fd_set集合的在线修改,所以下次再调用select之前还需要重置这3个文件描述符集合。

poll将文件描述符和事件都定义在pollfd结构体中,使得任何事件都能被统一处理,而且pollfd将监测事件和就绪事件分开了,保证events不被改变,因此pollfd不需要重置pllfd结构中的events成员。但是因为select和poll返回的都是整个事件集合,所以他们查找就绪事件的文件描述符的效率都是O(n)。

epoll在内核中维护了一个事件表,而且还提供一个函数epoll_ctl来向事件表中添加、删除、修改事件,所以它无须每次都重置事件。因为epoll返回的都是就绪事件,所以epoll查找就绪事件的文件描述符的时间复杂度都是O(1)。

与多进程/多线程服务器进行对比 它的优点在于:
1)不需要建立多个线程、进程就可以实现一对多的通信。
2)可以同时等待多个文件描述符,效率比起多进程多线程来说要高很多。
3)select()的可移植性更好,在某些Unix系统上不支持poll()
4)select() 对于超时值提供了更好的精度:微秒,而poll是毫秒

与多进程/多线程服务器进行对比 它的缺点在于:

1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大 ,循环次数有点多;
2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大 。
3)select支持的文件描述符数量太小了,默认是1024;

原创粉丝点击