什么是IO多路复⽤
I/O多路复⽤是⼀种在单个线程或进程中处理多个输⼊和输出操作的机制。它允许单个进程同时监视多个⽂件描述符(通常是套接字),当⼀个或多个⽂件描述符准备好读或写时,它就可以⽴即响应。
I/O多路复⽤通常通过select、poll、epoll等系统调⽤来实现。
select: select是⼀个最古⽼的I/O多路复⽤机制,它可以监视多个⽂件描述符的可读、可写和错误状态。然⽽,但是它的效率可能随着监视的⽂件描述符数量的增加⽽降低。
poll: poll是select的⼀种改进,它使⽤轮询⽅式来检查多个⽂件描述符的状态,避免了select中⽂件描述符数量有限的问题。但对于⼤量的⽂件描述符,poll的性能也可能变得不⾜够⾼效。
epoll: epoll是Linux特有的I/O多路复⽤机制,相较于select和poll,它在处理⼤量⽂件描述符时更加⾼效。epoll使⽤事件通知的⽅式,只有在⽂件描述符就绪时才会通知应⽤程序,⽽不需要应⽤程序轮询。
I/O多路复⽤允许在⼀个线程中处理多个I/O操作,避免了创建多个线程或进程的开销,允许在⼀个线程中处理多个I/O操作,避免了创建多个线程或进程的开销。
select/poll/epoll的区别和联系
select , poll 和 epoll 都是I/O多路复⽤技术,它们⽤于同时处理多个I/O操作,特别是在⾼并发⽹络编程中。
select
select 是最早的I/O多路复⽤技术,它可以同时监视多个⽂件描述符(file descriptor, FD)的I/O状态(如可读、可写、异常等)。 select 函数使⽤⼀个⽂件描述符集合(通常是⼀个位图)来表示要监视的⽂件描述符,当有I/O
事件发⽣时, select 会返回对应的⽂件描述符集合。
select的主要限制如下:
⽂件描述符数量限制: select 使⽤⼀个位图来表示⽂件描述符集合,这限制了它能够处理的⽂件描述符数量(通常是1024个)。
效率问题:当⽂件描述符数量较⼤时, select 需要遍历整个⽂件描述符集合来查找就绪的⽂件描述符,这会导致较低的效率。
⾮实时性:每次调⽤ select 时,需要重新设置⽂件描述符集合,这会增加函数调⽤的开销。
poll
poll 是为了克服 select 的限制⽽引⼊的⼀种I/O多路复⽤技术。 poll 使⽤⼀个⽂件描述符数组(通常是⼀个结构体数组)来表示要监视的⽂件描述符。与 select 类似, poll 可以监视多个⽂件描述符的I/O状态。
poll的优点如下:
⽂件描述符数量不受限制:由于 poll 使⽤⼀个动态数组来表示⽂件描述符,因此它可以处理任意数量的⽂件描述符。
效率相对较⾼: poll 在查找就绪的⽂件描述符时,只需要遍历实际使⽤的⽂件描述符数组,⽽不是整个⽂件描述符集合。
然⽽, poll 仍然存在⼀些问题:
效率问题:尽管 poll 相对于 select 具有较⾼的效率,但当⽂件描述符数量很⼤时,它仍然需要遍历整个⽂件描述符数组。
⾮实时性:与 select 类似,每次调⽤ poll 时,需要重新设置⽂件描述符数组。
epoll
epoll 是Linux特有的⼀种⾼效I/O多路复⽤技术,它克服了 select 和 poll 的主要限制。 epoll 使⽤⼀个事件驱动(event-driven)的⽅式来处理I/O操作,它只会返回就绪的⽂件描述符,⽽不是遍历整个⽂件描述符集合。
epoll的主要优点如下:
⾼效: epoll 使⽤事件驱动的⽅式来处理I/O操作,因此它在处理⼤量⽂件描述符时具有很⾼的效率。当有I/O事件发⽣时, epoll 可以⽴即得到通知,⽽⽆需遍历整个⽂件描述符集合。这使得 epoll 在⾼并发场景中具有更好的性能。
可扩展性:与 poll 类似, epoll 可以处理任意数量的⽂件描述符,因为它使⽤⼀个动态数据结构来表示⽂件描述符。
实时性: epoll 使⽤⼀个内核事件表来记录要监视的⽂件描述符和事件,因此在每次调⽤ epoll 时⽆需重新设置⽂件描述符集合。这可以减少函数调⽤的开销,并提⾼实时性。
epoll 具有诸多优点,但它⽬前仅在Linux平台上可⽤。对于其他平台,可能需要使⽤类似的I/O多路复⽤技术,如BSD中的 kqueue 。
总结: select 是最早的I/O多路复⽤技术,但受到⽂件描述符数量和效率⽅⾯的限制。 poll 克服了⽂件描述符数量的限制,但仍然存在⼀定的效率问题。 epoll 是⼀种⾼效的I/O多路复⽤技术,尤其适⽤于⾼并发场景,但它仅在Linux平台上可⽤。⼀般来说,epoll的效率是要⽐select和poll⾼的,但是对于活动连接较多的时候,由于回调函数触发的很频繁,其效率不⼀定⽐select和poll⾼。所以epoll在连接数量很多,但活动连接较⼩的情况性能体现的
⽐较明显。