这是之前在俱乐部邮件列表中讨论的一个问题。问题起于IBM DW上的一篇文章,也就是参考资料1。文章中对于IO模型的分类,采用同步、异步与阻塞、非阻塞交叉配对,形成了4中IO模型。让人总是感觉难以理解。
关于I/O Models,建议阅读《Unix Network Programming》Section 6.2
stevens将IO模式分为5种:
blocking I/O
nonblocking I/O
I/O multiplexing (select and poll)
signal driven I/O (SIGIO)
asynchronous I/O (the POSIX aio_functions)
关于同步与异步,POSIX标准的定义:
A synchronous I/O operation causes the requesting process to be
blocked until that I/O operation completes.
An asynchronous I/O operation does not cause the requesting
process to be blocked.
按照上面的定义划分:前四种都属于同步,
只有异步IO模式属于异步。
由于的当前操作系统的协议栈设计的HS/HA模型,决定了数据到达本地后,首先是放在kernel层中的一个缓冲区中,用户空间调用recv等API,将数据copy到用户空间。IO就包括两个阶段:等待数据有效,copy数据。UNP中有一个图描述了这5种modle的区别。
为了确认,我查了一下aio_read的用法,在glibc中找到一个测试例程,当程序发起aio_read()后,实际上系统调用马上返回了,但是数据却要异步随后到达,如果代码要处理read的数据,就必须有一个wait的过程,一般是循环调用aio_suspend(),判断是否有一个error为INPROGRESS,说明至少还有一个aio_read未完成,继续等待。当然,如果是aio_write(),而且只是写入文件的话,可以不用关心aio_write()何时结束。
因此,从上面分析看来,组合虽然有四种,但是实际上只有3种存在:同步阻塞、同步非阻塞、异步非阻塞。
阻塞的一定是同步;同步的不一定是阻塞,非阻塞的可以通过select等实现同步;异步肯定是非阻塞的,IO操作请求立刻返回了,具体操作在后台进行,数据异步到达。
---------------------------------------------------------------------------
同步方式容易理解,编程简单,但是效率比较低;异步方式不容易理解,而且编程也比较复杂。为了综合同步和异步的优点,有人提出了半同步半异步的模型。上层提供同步接口;下层使用异步实现。
参考资料4中讲述半同步半异步模型,其例子是协议栈的实现,讲到数据包的到达是异步的,达到后触发中断,进行中断响应,借用其他执行体的堆栈结构。给上层应用提供同步接口。上层应用是一个执行体顺序的执行,有自己独立的堆栈结构。
在HS-HA.pdf中,举的例子是协议栈的实现,讲到数据包的到达是异步的,达到后触发中断,进行中断响应,借用其他执行体的堆栈结构。同步是一个执行体顺序的执行,有自己独立的堆栈结构。像select和epoll等实现,他们这些是在IO就绪的时候,操作系统唤醒睡眠线程,还是在之前的上下文中处理。
---------------------------------------------------------------------------
参考:
http://www.ibm.com/developerworks/cn/linux/l-async/
阅读(673) | 评论(0) | 转发(0) |