IO 模型(BIO、NIO、多路复用)

IO 模型

BIO,阻塞IO

调用 receive 获取数据的时候,如果获取不到,会一直阻塞

一个连接,就要一个线程处理,那么当应用连接数量非常多的时候,就需要非常多的线程来处理,效率太低了

简单的说,大量线程带来的开销包括:

  1. 线程的内存开销
  2. 线程上下文切换的开销,包括保存和加载上下文,以及由于上下文切换导致的缓存不命中。

NIO,非阻塞IO

调用 receive 获取数据的时候,如果获取不到消息,会直接返回,可以使用一个线程管理多个连接,但是需要忙轮询,挨个去询问数据有没有到达,存在太多无效的询问了

多路复用

底层基于是 NIO,非阻塞IO
使用单个线程,监听多个 fd 文件描述符,可以通过多路复用选择器,通过不同的函数,获取到就绪的 fd,然后自己再去 receive 把数据从内核缓冲区拷贝到用户缓冲区中,这个过程是阻塞的,需要应用程序自己负责读写,所以多路复用属于同步 IO

多路复用选择器

select

每次调用 select 函数,都需要将 fd_set 的集合,从用户空间拷贝到内核缓冲区,返回结果的时候又需要从内核缓存区拷贝到用户空间

拿到函数的结果之后,无法直接知道具体是哪个 fd 就绪了,还需要 O(n) 的时间复杂度来遍历集合,来获取哪个 fd 就绪了

监听的 fd 数量、连接的个数有上限,默认不超过 1024 个

poll

和 select 类似,效率没有太大的提升

使用链表来存储 fd,没有了监听 fd 连接的个数上限,但是链表查找的时间复杂度是 O(n),当监听的 fd 数量多了之后,效率就会变差

拿到函数的结果之后,还需要 O(n) 的时间复杂度来遍历,获取哪个 fd 就绪了

epoll

对select 和 poll进行了巨大的改变

epoll实例中的红黑树保存要监听的FD,理论上无上限,而且增删改查的效率都非常高,性能也不会随着监听FD的数据增多而显著下降

每个FD只需要执行一次epoll-ctl添加到红黑树,以后每次epoll_wait无需传递任何参数,无需重复拷贝FD到内核空间

内核会将就绪的FD直接拷贝到用户空间的指定位置,用户进程无需遍历所有的FD,就能知道就绪的FD是谁

select和poll都只提供了一个函数——select或者poll函数。
而epoll提供了三个函数:epoll_create,epoll_ctl 和 epoll_wait,epoll_create 是创建一个 epoll 句柄;epoll_ctl 是注册要监听的事件类型;epoll_wait 则是等待事件的产生

epoll_create
创建 epoll 结构体

epoll_ctl
往红黑树中添加、移除 fd,当 fd 事件就绪之后,会触发函数回调,将就绪的 fd 放到就绪链表中

epoll_wait
返回就绪链表,通过 O(1) 的时间复杂度,就可以获取到就绪的 fd,然后自己再去 receive 把数据从内核缓冲区拷贝到用户缓冲区中

AIO,异步IO

把数据从内核缓冲区拷贝到用户缓冲区中,这个过程也不是阻塞的,异步I/O则无需应用程序自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间

相关推荐

  1. IO 模型(BIO、NIO、复用)

    2024-02-01 18:36:01       55 阅读
  2. IO复用

    2024-02-01 18:36:01       32 阅读
  3. io复用

    2024-02-01 18:36:01       27 阅读
  4. 网络编程:IO复用(五个IO模型

    2024-02-01 18:36:01       26 阅读
  5. IO复用服务器——select模型和poll模型

    2024-02-01 18:36:01       53 阅读
  6. IO复用

    2024-02-01 18:36:01       65 阅读
  7. Redis——IO复用

    2024-02-01 18:36:01       61 阅读
  8. IO复用--epoll

    2024-02-01 18:36:01       45 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-01 18:36:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-01 18:36:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-02-01 18:36:01       87 阅读
  4. Python语言-面向对象

    2024-02-01 18:36:01       96 阅读

热门阅读

  1. 127-前途与好人

    2024-02-01 18:36:01       47 阅读
  2. Shell - 学习笔记 - 2.6 - Shell $*和$@之间的区别

    2024-02-01 18:36:01       60 阅读
  3. Leetcode刷题(三十二)

    2024-02-01 18:36:01       55 阅读
  4. js跳转页面都有哪些方式?

    2024-02-01 18:36:01       66 阅读
  5. RK3568开发笔记-感光芯片ISL29035调试记录/IIO子系统

    2024-02-01 18:36:01       41 阅读
  6. 机器学习系列——(二)主要任务

    2024-02-01 18:36:01       55 阅读
  7. (安卓)跳转应用市场APP详情页的方式

    2024-02-01 18:36:01       55 阅读
  8. elementui 回到顶部报错

    2024-02-01 18:36:01       53 阅读
  9. basicPython-5

    2024-02-01 18:36:01       44 阅读