这篇文章我们来聊一个很简单,但是很多人往往分不清的一个问题,同步异步、阻塞非阻塞到底怎么区分?
开篇先问大家一个问题:IO多路复用是同步IO还是异步IO?
先思考一下,再继续往下读。
巨著《Unix网络编程》将IO模型划分为5种,分别是
- 阻塞IO
- 非阻塞IO
- IO复用
- 信号驱动IO
- 异步IO
个人认为这么分类并不是很好,因为从字面上理解阻塞IO和非阻塞IO就已经是数学意义上的全集了,怎么又冒出了后边3种模型,会给初学者带来一些困扰。
接下来进入正文。
1. 一个简单的IO流程
让我们先摒弃我们原本熟知的各种IO模型流程图,先看一个非常简单的IO流程,不涉及任何阻塞非阻塞、同步异步概念的图。

客户端发起系统调用之后,内核的操作可以被分成两步:
- 等待数据
此阶段网络数据进入网卡,然后网卡将数据放到指定的内存位置,此过程CPU无感知。然后经过网卡发起硬中断,再经过软中断,内核线程将数据发送到socket的内核缓冲区中。
- 数据拷贝
数据从socket的内核缓冲区拷贝到用户空间。
2. 阻塞与非阻塞
阻塞与非阻塞在API上区别在于socket是否设置了SOCK_NONBLOCK这个参数,默认情况下是阻塞的,设置了该参数则为非阻塞。
2.1 阻塞
假设socket为阻塞模式,则IO调用如下图所示。

文章介绍了IO模型的五种分类,强调阻塞和非阻塞主要关注系统调用期间线程的状态,而同步和异步关注结果获取方式。IO多路复用在应用程序层面上仍是同步的,因为它需要等待IO结果。理想的异步是内核直接返回结果,但Linux内核缺乏原生支持,常通过多线程模拟异步效果。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



