什么是IO的多路复用?
什么是IO的多路复用?
题眼:异步非阻塞模型,epoll
IO多路复用(I/O Multiplexing)是一种允许单个进程或线程监视多个输入/输出(I/O)通道(如文件描述符)的技术,如网络连接和文件。当某个I/O通道有数据可读取或可写入时,操作系统会通知应用程序,从而允许应用程序进行相应的I/O操作。
IO多路复用的主要目的是提高程序的并发能力,允许程序在单线程或单进程中处理多个I/O请求,而不是为每个I/O请求创建新的线程或进程。这样可以显著减少资源消耗,并提高程序的响应性和效率。
以下是几种常见的IO多路复用技术:
- select:
○ 最早的IO多路复用机制之一,允许程序监视多个文件描述符,直到它们中的一个或多个准备好进行I/O操作。 - poll:
○ 与select类似,但解决了select的一些限制,如文件描述符的数量限制和对文件描述符的线性扫描。 - epoll(Linux特有):
○ 一种高效的IO多路复用机制,专为处理大量并发连接而设计。epoll使用一组特定的数据结构来减少内核和用户空间之间的上下文切换。 - kqueue(BSD系统特有):
○ 类似于epoll,kqueue是一种高效的IO多路复用机制,可以监视多种类型的事件,包括I/O事件。 - IOCP(I/O Completion Ports,Windows特有):
○ 一种基于事件的I/O模型,允许程序在单线程中处理多个I/O操作,同时保持高性能。 - eventfd(Linux特有):
○ 一种用于线程间通信的文件描述符,可以用来实现事件通知机制。
IO多路复用技术通常与非阻塞I/O结合使用,使得应用程序可以在等待I/O操作完成时继续执行其他任务。这种模式是构建高性能网络服务器和客户端应用程序的关键技术之一。
参考答案:
IO多路复用的主要目的是提高程序的并发能力,允许程序在单线程或单进程中处理多个I/O请求,而不是为每个I/O请求创建新的线程或进程。这样可以显著减少资源消耗,并提高程序的响应性和效率。常见的多路复用有select、poll和epoll。
select和poll本身没啥区别,都是监听所有的IO文件描述符,select 实现多路复用的方式是,将已连接的 Socket 都放到一个文件描述符集合,然后调用 select 函数将文件描述符集合拷贝到内核里,让内核来检查是否有网络事件产生,检查的方式很粗暴,就是通过遍历文件描述符集合的方式,当检查到有事件产生后,将此 Socket 标记为可读或可写, 接着再把整个文件描述符集合拷贝回用户态里,然后用户态还需要再通过遍历的方法找到可读或可写的 Socket,然后再对其处理。但是他存在两个问题:它使用线性存储,时间复杂度是On,如果链接特别多的话,效果会变差;另外,它在调用活跃Socket时需要在内核态和用户态之间复制文件描述符,比较浪费资源。
epoll在原有的基础上使用了红黑树和事件驱动解决了这两个问题。首先,epoll在内核里使用了红黑树来保存文件描述符,红黑树可以提供稳定的Ologn操作,这样比较省时间。然后,它通过事件驱动的方式将活跃的文件描述符放在一个链表里,后续只需要操作这个链表,不需要像poll那样遍历整个集合。
引申:
1.这个问题也可以是:Linux的多路复用是如何实现的?select、poll和epoll有什么区别?C10k问题是如何解决的?
2.什么是边缘触发,什么是水平触发?
