几种IO

十三呀 2017-08-12
在工作学习中,我们常常会提到阻塞、非阻塞、同步异步。
而这几种方式有什么不同点呢?常常会把阻塞等同于同步,非阻塞等同于异步,而事实上却不然。
非阻塞的几种实现,poll、epoll等等实际上还是使用轮训方式去查看文件描述副或者其他状态,以确定数据是否已准备好,而这本质上还是同步的方式,真正的异步方式是在数据已经ready后由系统给应用程序发送信号,而不被需要应用程序自己去check。
因此我们用到的阻塞、非阻塞IO实际上都是同步的方式。
真正的异步IO有linux中的AIO。

高级IO中有一种方式内存映射,内存映射是指在IO时不需要将数据copy到内核空间,直接进入进程私有空间,少了几次copy,但坏处就是容易出现缺页异常。在java中可以使用RandomAccessFile类,而由于这种方式使用堆外内存,因此适用于处理大文件。
“直接 I/O 并不一定总能提供令人满意的性能上的飞跃。设置直接 I/O 的开销非常大,而直接 I/O 又不能提供缓存 I/O 的优势。缓存 I/O 的读操作可以从高速缓冲存储器中获取数据,而直接 I/O 的读数据操作会造成磁盘的同步读,这会带来性能上的差异 , 并且导致进程需要较长的时间才能执行完;对于写数据操作来说,使用直接 I/O 需要 write() 系统调用同步执行,否则应用程序将会不知道什...
在工作学习中,我们常常会提到阻塞、非阻塞、同步异步。
而这几种方式有什么不同点呢?常常会把阻塞等同于同步,非阻塞等同于异步,而事实上却不然。
非阻塞的几种实现,poll、epoll等等实际上还是使用轮训方式去查看文件描述副或者其他状态,以确定数据是否已准备好,而这本质上还是同步的方式,真正的异步方式是在数据已经ready后由系统给应用程序发送信号,而不被需要应用程序自己去check。
因此我们用到的阻塞、非阻塞IO实际上都是同步的方式。
真正的异步IO有linux中的AIO。

高级IO中有一种方式内存映射,内存映射是指在IO时不需要将数据copy到内核空间,直接进入进程私有空间,少了几次copy,但坏处就是容易出现缺页异常。在java中可以使用RandomAccessFile类,而由于这种方式使用堆外内存,因此适用于处理大文件。
“直接 I/O 并不一定总能提供令人满意的性能上的飞跃。设置直接 I/O 的开销非常大,而直接 I/O 又不能提供缓存 I/O 的优势。缓存 I/O 的读操作可以从高速缓冲存储器中获取数据,而直接 I/O 的读数据操作会造成磁盘的同步读,这会带来性能上的差异 , 并且导致进程需要较长的时间才能执行完;对于写数据操作来说,使用直接 I/O 需要 write() 系统调用同步执行,否则应用程序将会不知道什么时候才能够再次使用它的 I/O 缓冲区。与直接 I/O 读操作类似的是,直接 I/O 写操作也会导致应用程序关闭缓慢。所以,应用程序使用直接 I/O 进行数据传输的时候通常会和使用异步 I/O 结合使用。”
Zero copy技术。

直接I/O数据不经过内核空间,而与之对应的是另一种Zero Copy技术,数据不经过应用程序地址空间。
zero copy使用系统接口nmap或者更高阶的sendfile接口。
“在 Linux 中,减少拷贝次数的一种方法是调用 mmap() 来代替调用 read,比如:
         tmp_buf = mmap(file, len);
         write(socket, tmp_buf, len);
首先,应用程序调用了 mmap() 之后,数据会先通过 DMA 拷贝到操作系统内核的缓冲区中去。接着,应用程序跟操作系统共享这个缓冲区,这样,操作系统内核和应用程序存储空间就不需要再进行任何的数据拷贝操作。应用程序调用了 write() 之后,操作系统内核将数据从原来的内核缓冲区中拷贝到与 socket 相关的内核缓冲区中。接下来,数据从内核 socket 缓冲区拷贝到协议引擎中去,这是第三次数据拷贝操作。”

参考文献:
https://www.ibm.com/developerworks/cn/linux/l-cn-zerocopy2/index.html
https://www.ibm.com/developerworks/cn/linux/l-cn-directio/index.html
显示全文

查看更多主题的豆瓣日记和相册

十三呀
作者十三呀
3日记 1相册

全部回应 0 条

添加回应

十三呀的热门日记

值得一读

    豆瓣
    我们的精神角落
    免费下载 iOS / Android 版客户端
    App 内打开