技术对比
select()与poll()基本的优势是更轻便。缺点是:随着文件描述符的数量增加[成百上千级别],性能下降。
epoll()优势在于在高并发的情形下,性能显著的优于select()与poll()
总之:select()与poll()更轻便,epoll()的性能更好。
水平触发与边沿触发通知
水平触发通知(LT):当文件描述符就绪时[可以无阻塞的实现IO系统调用]
边沿触发通知(ET):当文件描述符上有新的事件发生时【例如新的输入等事件】
select()与poll() 使用水平触发,epoll两者均可以使用,默认是水平触发。
两种模型的区别:
1.使用水平触发通知时,允许我们在任意时刻监控IO,因此没有必要每次都做过多的IO操作(例如,尽可能的读取更多的字节流)
2.对于边沿触发通知,只有在IO事件发生时才能接收到通知。以后再有IO事件到来时,不会做进一步的通知。而且当IO事件通知文件描述符时,我们通常不知道有多少IO是合适的(例如:有多少byte可以读取)
3.边沿触发通知的设计原则:
a)当发生IO事件通知时,程序应该尽可能的使用IO(ex:尽可能读取更多的比特),若在IO期间发生错误,会丢失大量的数据。
b)所有文件描述符应该设置为非阻塞的状态模式。在接收到边沿触发通知后,应该重复的执行IO操作,直到发生系统调用相关的失效错误:EAGAIN 或EWOULDBLOCK.
文件描述符就绪的条件。
只要调用IO函数时,没有被阻塞,文件描述符就进入就绪(ready)的状态。不管函数是否传输数据。
也就是说,select()和poll()函数告我我们IO操作不会被阻塞,而并不会检查是否能成功的传输数据。
select()与poll()对比
相同点
实现细节:都是使用相同的内核轮询技术。
API不同点
► select(),默认监控的文件描述符上限是1024. poll()没有限制。
► select()的fd_set参数在每次循环中必须重新初始化,poll()不必如此
► timeout的精度,select()是微秒级别,poll()精确到毫秒级别。select性能更好
► 文件描述符关闭后,poll()会通知是那个关闭,select()只会返回-1和error
性能
性能相近的情形:
1.监控的文件描述符的个数较少,
2.文件描述符的数量大,而且比较密集
性能显著区别的情形:
监控的文件描述符比较稀疏的情形下,poll()性能优于select()
稀疏:监控的文件描述符的上限值(最大值)很高,但是实际上只有一小部分文件描述符正在被监控。
select()与poll()的弊端
当监控大量的文件描述符时,存在下列问题:
1.每次调用select()与poll(),都要检查指定的文件描述符是否是ready的状态,当文件描述符的数量十分大时,这种操作十分耗时
2.每次调用select()与poll(),都要传递已经被监控的文件描述符的数据结构给内核。
3.在每次调用select()与poll()之后,程序必须检查函数返回值,看看哪些文件描述是ready的状态。
而epoll函数可以使内核只记录进程相关的文件描述符,可以避免select()与poll()在文件描述符数量较大时带来的问题。
epoll API
1.epoll在监控大量描述符的条件下,性能优于select()与poll()。
2.epoll支持水平触发与边缘触发通知,而select()与poll()仅仅支持水平触发通知。
epoll使用专门的数据结构记录:
1,特定的文件描述符列表。 epoll_ctl()提供文件描述符列表的修改
2,已经ready的IO列表。
epoll 与I/O 复用性能对比:
文件描述符的数量N | poll() CPU 时间(s) | select() CPU 时间(s) | epoll CPU 时间(s) |
---|---|---|---|
10 | 0.61 | 0.73 | 0.41 |
100 | 2.9 | 3.0 | 0.42 |
1000 | 35 | 35 | 0.53 |
10000 | 990 | 930 | 0.66 |
1> poll(),select()的处理时间随文件描述符的大小N线性增大
2> epoll()的处理时间随着N的增大,处理时间只是小幅增加
epoll()性能更优的原因
a)每次调用select()和poll(),内核需要检查所有的文件描述符。于此相反,epoll使用epoll_ctl函数监控特定的文件描述符。
b)每次调用select()和poll(),都需要传递一个记录所有被监控的文件描述符的数据结构给内核。于此相反,对于epoll,我们用epoll_ctl函数在内核空间建造数据结构来记录被监控的文件描述符集合。一旦这个数据结构在内核建立,之后每次调用epoll_wait都不必再传递数据结构给内核。