阻塞/非阻塞IO和同步/异步IO

3 篇文章 0 订阅
2 篇文章 0 订阅


前言

IO是个比较废人思量的东西,不管是自己理解,还是面试提问。

一、IO的理解

  1. IO的作用一般分为,获取文件数据或网络请求数据。
  2. 数据处理过程其实分为两阶段:A. 内核准备数据(把数据从网卡拷贝到socket缓冲区或者把文件数据从磁盘拷贝到内核的page cache);B. 把数据从内核的内存拷贝给用户的用户进程(用户空间)。
  3. 其实阻塞/非阻塞是针对A阶段而言;而同步/异步是针对B阶段而言

二、IO的使用

1.传统IO-阻塞IO:BIO

传统IO,咱们是通过read这个系统调用进行数据获取,A阶段和B阶段是不分开的,知道B阶段完成,用户进程获取到数据,才可以使用数据。所以传统IO是同步阻塞的。

2.非阻塞IO:NonBlocking IO

由于传统IO的使用,对于用户来说,不透明。而且CPU也无事可做,浪费了CPU。
因此前人对内核进行了优化,但是优化主要是集中在A阶段,也就是把A阶段变为非阻塞的。具体的做法就是使得内核支持,在用户程序调用read的时候,如果内核page cache还没准备好数据,返回-1,这样用户程序便可以去处理自己的用户逻辑。不过用户程序便因此需要不停轮询调用read操作来试探内核,直到内核返回数据,那么会发起系统调用,进行B阶段,等待数据拷贝。
优点:
用户程序可以在IO过程中,利用CPU处理一些其他逻辑操作,用户程序具有更大的主观作用。
缺点:

  1. 这种情况,其实对于大多数程序而言并不是多大的优化,因为大多数用户程序在没有IO数据的时候,CPU也无事可做;
  2. 而且因为轮询,导致系统调用次数大量增加,而系统调用,CPU要陷入内核态,还要发生进程切换,涉及到进程上下文的保存和切换,比较耗费性能;
  3. 如果需要进行的IO操作太多,那么系统调用数据量更大了。

3. New IO : NIO

内核进一步优化:
主要是针对上述 非阻塞IO的缺点的第三点。当服务端维护了和用户创建的很多网络请求之后,那么使用非阻塞IO就会需要发生太多次系统调用,来处理用户请求。服务器性能将急剧下降。然后内核就进一步优化了,支持了多路复用器,也就是NIO,服务器的用户进程把维护的网络请求的文件描述符(fd)注册到selector上,然后阻塞到该selector,直到selector关心的fd列表中,某个fd有了事件返回。
当然selector的使用必须要支持轮询,因为当有fd返回时,并不是所有的fd都返回了,所以多路复用器selector的使用前提就是要支持非阻塞IO。
这种方式减少系统调用的逻辑:是把系统调用的次数和网络连接的N变得没有关联关系。
在selector返回了fd列表之后,用户程序再通过系统调用,发起B阶段,等待数据拷贝

4. 异步IO:AIO

通过对上面三种情况的介绍,内核针对IO的优化,可以发现,其实都是针对A阶段的优化,进一步减少系统调用,也因此减少了B阶段。所以其实发生的一直都还是同步IO,那么有没有异步IO呢,异步IO又是什么呢?异步IO其实是想实现,发生系统调用之后,用户进程就返回了,不需要阻塞,后续内核执行完A和B阶段之后,再通知用户进程,然后用户进程可以直接处理数据。

但是目前Linux系统还是不支持异步IO的,而Linux系统又是主流服务器系统,所以现在可以理解为目前主流服务器不支持AIO;但是Windows系统其实已经支持了AIO了。想进一步理解的,可以去搜索了解。

总结

一直对阻塞/非阻塞IO和同步/异步IO混淆,最近理解之后,记录下来,多看看,方便理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值