
阻塞式I/O的弊端:传统的阻塞式I/O模型中,进程一旦进行I/O读写就会阻塞,导致整个系统的吞吐量急剧下降。为了处理多个I/O操作,可能需要创建大量的线程或进程,但这会带来线程或进程切换的开销,浪费CPU资源。
多路复用(I/O Multiplexing):同时监视多个文件描述符(文件句柄),当某个文件描述符就绪(一般是读写就绪)时,就通知程序进行相应的操作。
select的本质是将判断某个文件描述符(TCP中通常是socket,因为多个客户端和服务器通信,服务器就需要建立多个socket)是否处于就绪状态(就绪状态是指socket进入可读、可写、异常的某一种状态(比较重要),也有地方描述为socket可以进行IO操作的状态)的工作交给后台,这个时间你可以去处理其它的事情,等后台处理完了返回给你一个新的就绪状态的文件描述符集,你就可以接着处理这些处于就绪状态的socket连接。
select会将应用层文件描述符集以位图形式拷贝到内核,内核处理完后会将改变的文件描述符集返回给应用层。
优点:可以同时处理多个连接,避免了大量的线程或进程切换,提高了系统的并发性能。 缺点:在大量文件描述符的情况下,select的性能会受到限制,因为它需要轮询所有的文件描述符。此外,由于select使用位图来存储文件描述符,因此文件描述符的集合大小是有限制的。
poll:与select类似,但克服了select的一些限制,如文件描述符集合的大小。但poll在大量文件描述符的情况下性能仍然不佳。 epoll:Linux特有的I/O多路复用技术,使用事件驱动的方式,当文件描述符就绪时,会触发相应的事件,从而避免了轮询的开销。epoll在大量文件描述符的情况下性能更好。