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

一个典型的网络IO接口调用,分为两个阶段,分别是“数据就绪” 和 “数据读写

  • 数据就绪阶段分为 阻塞和非阻塞,以read为例, 表现就是,若读缓冲区为空, 则阻塞会阻塞当前线程(其实也不会浪费系统资源, 阻塞时CPU会调度其他进程运行); 若非阻塞, 如果读缓冲区为空则会直接返回, 若不为空, 则内核将读缓冲区的数据拷贝到buf内再返回, 对于非阻塞, 可以根据返回值判断读写的情况
  1. 阻塞
    如果read的时候, 若它的读缓冲区为空, 默认这个函数会阻塞在这, 等到有数据才会去读并返回, 才能往下执行
  2. 非阻塞
    若设置socket的flags为O_NONBLOCK, 即使读缓冲区为空, read调用也会立刻返回, 我们可以根据返回值来判断发生了什么事
  • 数据读写阶段分为同步和异步, 说的是应用程序和内核的交互方式. 同步表示A向B请求调用一个网络IO接口时(或者调用某个业务逻辑API接口时),数据的读写都是由请求方A自己来完成的(不管是阻塞还是非阻塞);异步表示A向B请求调用一个网络IO接口时 (或者调用某个业务逻辑API接口时),向B传入请求的事件以及事件发生时通知的方式,A就可以 处理其它逻辑了,当B监听到事件处理完成后,会用事先约定好的通知方式,通知A处理结果。
  1. 同步
    如果read的时候, 读缓冲区有数据, 那么内核会去读, 并且把读缓冲区中的数据拷贝到read指定的栈中的buf中, 在这段时间内不能做其他事情, 必须等拷贝结束才能返回, 接着往下执行
  2. 异步
    通过linux提供的aio_read这个异步调用, 将要读的sockfd, 以及拷贝到哪里(即buf), 通知方式(一般是信号)告诉内核, 然后aio_read就能返回, 接着执行后面的事情, 不浪费当前进程的时间, 等进程读完会以我们设置的通知方式告诉进程, 我们再来处理

总结:
在处理I/O时, 阻塞和非阻塞都是同步I/O(因为都是应用程序在操作), 只有使用类似aio_read, aio_write这样的异步I/O才是异步I/O(相当于将事情安排给内核做, 这段时间我们可以去做别的事情)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值