Netty 实现IO多路复用有几种方式?

1 个回答

  • 罗天
    先解决心情在解决事情。
    ## 什么是IO多路复用 利用IO多路复用模型,就可以实现一个线程监视多个文件句柄。当某个文件句柄就绪后,就能够通知到应用程序去处理对应IO事件。没有文件句柄就绪时就会阻塞应用程序,从而释放CPU资源。 ### IO 在操作系统中,数据在内核态和用户态进行读写操作。一般情况下指网络IO ### 多路 指的是多个TCP连接,如多个scocket或多个channel ### 复用 一个或多个线程资源 ### 目的 在并发请求中,通过一个或多个线程处理多个TCP连接,而无需创建和维护过多的线程,节省系统资源。 ## Select ### 工作过程 - select函数中存在三种fds,分别代表三种事件,readfds表示读描述符集合,writefds表示读描述符集合,exceptfds表示异常描述符集合 - 调用select之后,select会将fd_set从用户空间拷贝到内核空间 - 拷贝完成后,开始轮询每个fd - 当有就绪的事件后,通知用户线程 - 用户线程收到通知后,开始遍历用户空间的fd,得到就绪的事件,进行处理 ![image.png](https://images.codewd.com/a8901ef24d69c79dc79633d92d2d8812.jpg "image.png") ### 优点 跨平台支持性比较好,几乎所有平台都支持 ### 缺点 - 调用seelct之后,需要将fds从用户空间拷贝到内核空间 - 随着fd数量增多,性能随之下降,因为需要遍历每个fd - 操作系统对进程打开的fd数量有限制,一般默认为1024个 ## Poll 和select基本一样,不过它的存储方式是采用链表结构,没有最大文件描述符限制。 所以它的缺点比select少一个,其它优缺点都一样。 ## Epoll ### 存储结构 - 红黑树:通过红黑树来管理用户主进程accept添加进来的所有 socket 连接。 - 链表:当有连接就绪的时候,内核会把就绪的连接放到 rdllist 链表里,方便用户线程只遍历准备就绪的事件 ### 工作过程 - 在使用epoll时,首先会构建epoll对象。 - 有客户端接入时,会插入到epoll对象中 - 一旦fd就绪,会触发回调把fd插入到就绪链表中,并唤醒等待队列中的线程。 - 调用epoll_wait方法时只需要检查就绪链表,如有则返回给用户程序,如没有进入等待队列。 ### 优点 - 不需要遍历所有fd - 只需拷贝一次fd - 支持异步回调,避免无效轮询 - 不受fd数量影响 ### 缺点 只有Linux平台支持 ## 区别 ![image.png](https://images.codewd.com/2d92a4568f3eb9a28bf97a38a7b7525d.jpg "image.png")
    发布于 2025-07-18 06:46 •IP属地 江西
    举报
    评论
    收藏