同步与异步IO、阻塞与非阻塞IO
(2010-04-28 10:42)
分类: Linux_kernel
同步与异步IO、阻塞与非阻塞IO
很多时候我们常常看到同步与异步,阻塞与非阻塞的出现。有的地方直接将同步与阻塞画上了等号。异步与非阻塞画上了等号。事实上这是不对的。同步不等于阻
塞,而异步也不等于非阻塞。下面就来仔细的看看同步与异步、阻塞与非阻塞的概念差别,及他们的组合应用。 上面这些概念都是教科书的概念,下面谈谈个人的理解。所谓同步就是当一个进程发起一个函数(任务)调用的时候,一直会到函数(任务)完成。进程继续往下执行。而异步这不会这样,异步情况下是当一个进程发
起一个函数(任务)调用的时候,不会等函数返回,而是继续往下执行当,函数返回的时候通过状态、通知、事件。等方式通知进程任务完成。 而阻塞和非阻塞的概念相对明了多了。阻塞是当请求不能满足的时候就试进程挂起,非阻塞则是直接返回。 它们的组合:(网络装载) 图 2 给出了传统的阻塞 I/O
模型,这也是目前应用程序中最为常用的一种模型。其行为非常容易理解,其用法对于典型的应用程序来说都非常有效。在调用 read 系统调用时,应用程序会阻塞并对内核进行上下文切换。然后会触发读操作,当响应返回时(从我们正 在从中读取的设备中返回),数据就被移动到用户空间的缓冲区中。然后应用程序就会解除阻塞(read 调用返 回)。 图 2. 同步阻塞 I/O 模型的典型流程 从应用程序的角度来说,read 调用会延续很长时间。实际上,在内核执行读操作和其他工作时,应用程序的确会被阻塞。 PS. 我理解这里的意思是,read请求是阻塞的,也没有异步通知机制,因为应用程序一直在这个过程中等待,即一直在主动查询,所以是同步的。(顺序) 同步非阻塞 I/O 同步阻塞 I/O 的一种效率稍低的变种是同步非阻塞 I/O。在这种模型中,设备是以非阻塞的形式打开的。这意味着 I/O 操作不会立即完成,read 操作可能会返回一个错误代码,说明这个命令不能立即满足(EAGAIN 或 EWOULDBLOCK),如图 3 所示。 图 3. 同步非阻塞 I/O 模型的典型流程 非阻塞的实现是 I/O 命令可能并不会立即满足,需要应用程序调用许多次来等待操作完成。这可能效率不高,因为在很多情况下,当内核执行这个命令时,应用程序必须要进行忙
碌等待,直到数据可用为止,或者试图执行其他工作。正如图 3 所示的一样,这个方法可以引入 I/O 操作的延时,因为数据在内核中变为可用到用户调用 read 返回数据之间存在一定的间隔,这会导致整体数据吞吐量的降低。 PS. 我理解这里的意思是,read请求是非阻塞的,但是这里没有异步通知机制,而需要应用程序主动查询,所以是同步的。(多次试探) 异步阻塞 I/O 另外一个阻塞解决方案是带有阻塞通知的非阻塞 I/O。在这种模型中,配置的是非阻塞 I/O,然后使用阻塞 select 系统调用来确定一个 I/O 描述符何时有操作。使 select 调用非常有趣的是它可以用来为多个描述符提供通知,而不仅仅为一个描述符提供通知。对于每个提示符来说,我们可以请求这个描述符可以写数据、有读数据可用
以及是否发生错误的通知。 图 4. 异步阻塞 I/O 模型的典型流程 (select) select 调用的主要问题是它的效率不是非常高。尽管这是异步通知使用的一种方便模型,但是对于高性能的 I/O 操作来说不建议使用。 PS. 我理解这里的意思是,read请求实际上是非阻塞的,但是在异步通知方式上,采用了阻塞的slect系统调用,导致应用程序被阻塞,所以虽然异步,但任然阻 塞。(等待通知,自己完成) 异步非阻塞 I/O(AIO) 最后,异步非阻塞 I/O 模型是一种处理与 I/O 重叠进行的模型。读请求会立即返回,说明 read 请求已经成功发起了。在后台完成读
操作时,应用程序然后会执行其他处理操作。当 read 的响应到达时,就会产生一个信号或执 行一个基于线程的回调函数来完成这次 I/O 处理过程。 在一个进程中为了执行多个 I/O 请求而对计算操作和 I/O 处理进行重叠处理的能力利用了处理速度与 I/O 速度之间的差异。当一个或多个 I/O 请求挂起时,CPU 可以执行其他任务;或者更为常见的是,在发起其他 I/O 的同时对已经完成的 I/O 进行操作。 PS. 我理解这里的意思是,read请求实际上是非阻塞的,但是在异步通知方式上,采用了回调函数,无需应用程序再去处理。(委托完成) 异步 I/O 的动机 从前面 I/O 模型的分类中,我们可以看出 AIO 的动机。阻塞模型要求在 I/O 操作开始时阻塞应用程序,这意味着不可能同时重叠进行处理和 I/O 操作。同步非阻塞模型允许处理和 I/O 操作重叠进行,但是这需要应用程序根据重现的规则来检查 I/O 操作的状态。这样就剩下异步非阻塞 I/O 了,它允许处理和 I/O 操作重叠进行,包括 I/O 操作完成的通知。 这里我要特别强调一下异步IO和非阻塞IO的区别,异步IO就是把IO提交给系统,让系统替你做,做完了再
用某种方式通知你;非阻塞IO就是你要通过某种方式不定时地向系统询问你是否可以开始做某个IO,当可以开始后,还是要自己来完成IO |
|