说到这里,就得说说同步I/O和异步I/O的区别了。在有些时候,同步和异步、阻塞和非阻塞很容易被混用,其实它们完全不是一回事,而且它们修饰的对象也不同。阻塞和非阻塞是指当进程访问的数据如果尚未就绪,进程是否需要等待,简单说这相当于函数内部的实现区别,即未就绪时是直接返回还是等待就绪;而同步和异步是指访问数据的机制,同步一般指主动请求并等待I/O操作完毕的方式,当数据就绪后在读写的时候必须阻塞,异步则指主动请求数据后便可以继续处理其他任务,随后等待I/O操作完毕的通知,这可以使进程在数据读写时也不发生阻塞。
POSIX1003.1标准为异步方式访问文件定义了一套库函数,这里的异步I/O(AIO)实际上就是指当用户态进程调用库函数访问文件时,进行必要的快速注册,比如进入读写操作队列,然后函数马上返回,这时候真正的I/O传输还没有开始呢。
可以看出,这种机制是真正意义上的异步I/O,而且是非阻塞的,它可以使进程在发起I/O操作后继续运行,让CPU处理和I/O操作达到更好的重叠。
POSIX的标准库中定义了AIO的一系列接口,它几乎屏蔽了一切网络通信的细节,所以对使用者而言非常简单。AIO没有提供非阻塞的open()方法,所以进程仍然使用open()系统调用来打开文件,然后填充一些描述I/O请求的数据结构,接下来调用aio_read()或aio_write()来发起异步I/O操作,一旦请求进入操作队列后,函数便返回,进程可以在此后通过aio_error()来检查正在运行的I/O操作的状态。
然而对于AIO的实现,不同的平台有不同的方法,它甚至可以完全由库函数来实现而不需要内核的支持,比如通过多线程来模拟非阻塞的aio_read()调用。但是这样一来,它的性能便大打折扣,变得毫无意义,所以实际上很多平台都没有实现它。
在Linux 2.6.16中,AIO的实现可以在/usr/include/libaio.h中看到,它采用了一套没有遵循POSIX AIO标准的接口,并且实现方式正是基于LinuxThreads内核级线程库,截至目前,这个功能还在实现中,目前的Linux AIO只能用于通过O_DIRECT标志打开的文件。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。