非阻塞IO(NIO)

非阻塞IO(NIO)

一、前言

1.1、阻塞IO,BIO

BIO(Blocking I/O)
也称作同步阻塞IO。

1.2、非阻塞IO,NIO

NIO(Non-blocking I/O)
也称作同步非阻塞IO;
现在常用的NIO,是NIO+IO多路复用的结合体,epoll 还是会阻塞线程,不是真正的非阻塞IO。

1.3、异步IO,AIO

AIO(Asynchronous I/O)

二、同步/异步 和 阻塞/非阻塞

2.1 概念

  1. 同步
    调用方发起一个功能调用时,在没有得到功能的结果之前,该调用不会返回。也就是调用方会等待被调用方返回功能的结果。
  2. 异步
    调用方发起一个功能调用时,没有得到功能的结果立即返回,后续被调用方再通过回调等手段,把功能的结果通知调用方。也就调用方立即得到返回,但是返回中不包含功能结果。

Linux 的 AIO 中,异步的结果是通过内核的回调拿到的

  1. 阻塞
    线程发起一个调用时,在调用返回之前,线程会被阻塞,在这个状态下会交出当前CPU的使用权限而暂停。也就是调用方会等待调用结果,调用阻塞了调用方的线程,线程不在运行处理中。
  2. 非阻塞
    线程发起一个调用时,调用会立即返回,避免线程被阻塞。但是返回结果只是被调用方当前状态的值,实际使用时,调用方需要轮询,走到返回结果符合预期(直到数据准备好)

2.2 区别

  1. 同步和异步的区别
    区别是,调用方是否能够直接得到功能结果。
    同步会一直等待,直接到得到功能结果。
    异步会立即得到一个不包含结果的返回,功能的结果要由被调用方通知。
  2. 阻塞和非阻塞的区别
    区别是,调用是否公立即返回,进而是否阻塞调用方线程,在网络IO中,是指在数据未准备好的情况下,是否会阻塞线程走到数据准备好。
    阻塞会阻塞线程,调用方只能等待。
    非阻塞由于调用立即返回,而不阻塞线程,调用方可以继续做别的事情。
  3. 同步和阻塞区别
    区别是,是否会阻塞调用方线程。
    同步不会阻塞调用方线程,线程在运行处理中,中是逻辑上调用未返回而已。
    阻塞会阻塞调用方线程,线程不在运行处理中。
  4. 同步异步和阻塞非阻塞的区别
    区别是,讨论点不同。
    同步异步,讨论的是被调用方返回结果的通知机制。
    阻塞非阻塞,讨论的是,调用方的线程状态。

三、NIO 的演变

3.1 NIO 的诞生

  • 前置知识
    假设在 Linux 上运行应用,该应用监听了某个端口,通过网络获取外部数据。应用(application)是运行在Linux 的用户空间的,而外部数据是在Linux的内核空间中接收到的。
    请添加图片描述
  • 外部数据先到网卡、现保存到内核缓冲区、最后进入应用缓冲区。
  • 应用调用 read 方法读取外部数据,Linux 的内核操作分为 2 步:
  1. 等待数据就绪
  2. 把内核缓存区的数据复制到用户缓存区
1. BIO
  • Linux 的IO模型最初的是BIO
    请添加图片描述
    BIO一次 read(),触发了内核的两步操作,全程都阻塞。
  • 优点:线程阻塞时,消耗的CPU资源小。
  • 缺点:高并发时容易耗尽线程资源,且大量线程会引起线程切换的巨大开销,造成响应不及时。
2. NIO

请添加图片描述
NIO,靠着Linux 提供的可以立即返回的read(),在第一步中是不阻塞的,在第二步中仍然是阻塞的。

  • 优点:把应用线程的read调用,分割出了第一步和第二步,应用线程可以做更多实时的控制。
  • 缺点:第一步中的轮询,大量点用CPU时间,降低系统资源利用率,所以一般web服务器也不使用这样的NIO
    为了解决NIO轮询的缺点,引入了IO多路复用,用操作系统的IO多路复用,来替代轮询。
3. IO多路复用

IO多路复用是一种同步IO模型,是操作系统提供的能力,使用少量线程监听Linux的多个IO文件描述符,也就是线程复用于多个IO请求。
如果有任意IO文件描述符就绪,就会告知应用进行读取;如果没IO文件描述符就绪,就会阻塞应用线程。
Linux 中,IO多路复用的实现是 select/poll/epoll

IO多路复用的作用: 线程复用于多个请求,用较小的线程开销来支持更多的并发请求
请添加图片描述
NIO结合IO多路复用后,select/poll/epoll替代了轮询

  • Linux 上的 IO 多路复用演变经历了3个阶段:
    一、select
    二、poll
    三、epoll
    目前使用的是 epoll,默认是 epoll的水平触发模式(LT),还有一个边缘触发模式(ET),应用一般是用LT。
  1. select
    轮询遍历IO文件描述符,O(n)的线性时间复杂度,因此随着IO文件描述符的增多,性能下降。
    单进各能够打开的文件描述符有数量限制,导致应用的最大连接数是1024.
    调用select时,还需要文件描述符在用户空间和内核空间的拷贝,影响性能。

  2. poll
    同样是轮询遍历IO文件描述符,O(n)的线性时间复杂度,因此随着IO文件描述符的增多,性能下降。
    无文件描述符的数量限制。
    调用poll时,还需要文件描述符在用户空间和内核的拷贝,影响性能。

  3. epoll
    解决了select和poll的全部缺点,采用注册回调机制,替代了轮询遍历,无文件描述符的数量限制。
    利用mmap减少了文件描述符在用户空间和内核空间的拷贝,因此性能高。

原文链接:https://blog.csdn.net/lic721/article/details/126842761


若有凝问或错误,请指出,我好及时改正,让我们一起进步!
email : binary_space@126.com
qq : 103 586 2795
敲门砖: 代码谱写人生

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

征客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值