Linux IO漫谈
本文为原创,转载请注明:http://www.cnblogs.com/gistao/
Background
IO可能是我们接触最频繁的系统调用,比如printf到终端,send content到对端,而今天要讨论的仅是Linux平台下访问本机存储设备相关的IO。如果你对IO相关api的优缺点门清,可以忽略这个随笔啦。
read
read的过程大致如下:
- 用户malloc出一块内存,然后陷入内核。
- 内核从磁盘读取内容拷贝到cache。
- 内核将内容拷贝到用户内存。
缺点比较明显,需要两次拷贝,拷贝是非常耗cpu的。
O_DIRECT
open函数的参数里有这样一个flag,意思是说不需要内核做cache了,内核直接把数据memcpy给用户就好了,这样的优点是可以减少memcpy。但缺点也很明显,没有cache了。
pread
多线程代码并发的访问同一文件是常见的,示例代码如下:
pthread_mutex_lock (mutex); lseek (SEEK_SET+1024);
read (buf); pthread_mutex_unlock (mutex);
这里锁的意义是防治文件指针被其他线程seek走,导致本次read错乱,如何避免掉这个锁呢,就是pread,此函数和read的功能一样,但增加了一个要读取的offset参数,这样就不需要我们显示的加锁了,也许你会联想到strtok和strtok_r。代码改动如下:
pread (fd, buf, offset);
readahead
有时又会遇到下边代码的场景
while (n < max) {
read (buf[i]);
on_handle (buf[i]);
}
read函数是阻塞的,所以执行时间就等于max*time,即串行执行。可不可以非阻塞,就是readahead,此函数意思是在read之前,非阻塞的通知内核一下我要读的内容,内核会并发的预读这些内容进cache,当后续进行read时会大大的减少时间,代码修改成这样:
while (n < max) {
readahead (offset);
}
while (n < max) {
read (buf[i]);
on_handle (buf[i]);
}
mmap
mmap的详细原理不在这里讨论,见图

简单来说,是将内核空间映射到了用户空间,这样相比read函数来说减少了一次memcpy。
而mmap比O_DIRECT也有个好处是它确实利用了cache,可是对于普通的read来说,它利用的又不够充分,因为并不是每次访问都需要内核参与。不过有个补足办法就是用readahead,它可以传递你的意图(利用cache)给内核,从而避免了缺点。示例代码如下:
readahead (fd , offset);
ptr = mmap (fd);
a = ptr[offset];
aio
从以上可以看出来,IO模式是从阻塞提升到了非阻塞,性能优化围绕着cache和memcpy,那有没有一种非阻塞的,有cache的,最少memcpy的,这些都符合的技术,那应该就是aio了吧,但Linux的aio到现在也没有一个很好的实现,也许过于复杂吧,反过来看下Window平台,这都真不是事。下图是aio模型:

Final
有了mmap+ahead,aio真的还那么重要吗?真的很重要,没有真正的异步,就没有真正的并行编程,不能实现真正的async和await语法糖,比如一个异步方法要求10ms必须返回,而系统调用就得50ms完成,怎么可能是真正的async。但是如果不吹毛求疵,或追求极致的话,目前确实够用了,通过以上总结,希望能在IO编程时给你些选择素材。
Linux IO漫谈的更多相关文章
- 【知乎网】Linux IO 多路复用 是什么意思?
提问一: Linux IO多路复用有 epoll, poll, select,知道epoll性能比其他几者要好.也在网上查了一下这几者的区别,表示没有弄明白. IO多路复用是什么意思,在实际的应用中是 ...
- Linux IO模型和网络编程模型
术语概念描述: IO有内存IO.网络IO和磁盘IO三种,通常我们说的IO指的是后两者. 阻塞和非阻塞,是函数/方法的实现方式,即在数据就绪之前是立刻返回还是等待. 以文件IO为例,一个IO读过程是文件 ...
- block_dump观察Linux IO写入的具体文件(mysqld)
一.使用方法: 二.基本原理: 三.总结 很多情况下开发者调测程序需要在Linux下获取具体的IO的状况,目前常用的IO观察工具用vmstat和iostat,具体功能上说当然是iostat更胜一筹 ...
- linux io优化
场景:xml文件解析入库:并备份 问题:磁盘io异常,经常100%busy: linux io优化方法: 1.修改磁盘挂着参数,修改为writeback模式:对于文件读取频繁的可以设置noatime: ...
- Linux IO 调度器
Linux IO Scheduler(Linux IO 调度器) 每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交 ...
- Linux IO工具 iotop备择方案iopp
iotop毫无疑问linux IO检测上是一个很好的工具,但苦于要求和内核版本Python版本号.我的很多朋友放弃了.我也是.无意中发现iopp,使用c书面,与此iotop它是一个作用.nice! 一 ...
- 【转】linux IO子系统和文件系统读写流程
原文地址:linux IO子系统和文件系统读写流程 我们含有分析的,是基于2.6.32及其后的内核. 我们在linux上总是要保存数据,数据要么保存在文件系统里(如ext3),要么就保存在裸设备里.我 ...
- Linux IO时事检测工具iostat
Linux IO时事检测工具iostat iostat命令用于检测linux系统io设备的负载情况,运行iostat将显示自上次运行该命令以后的统计信息.用户可以通过指定统计的次数和时间来获得所需的统 ...
- Linux IO Scheduler(Linux IO 调度器)【转】
每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交的request.I/O调度器的基本目的是将请求按照它们对应在块设 ...
随机推荐
- 【转】valueof()用法
valueOf()用来返回对象的原始类型的值. 语法 booleanObject.valueOf() 代码:<script> var a = new String("valueO ...
- onethinkp导入excel
/** * Excel导入函数 * @author crx349 */ if (!empty($_FILES)) { $config = array( 'maxSize' => 3145728, ...
- C++小项目:directx11图形程序(六):cameraclass
cameraclass是一个相机类,它的作用是生成非常重要的观察矩阵.本小节涉及到一点数学知识,相对前面需要只是填充,调用,算是比较有趣的吧. cameraclass.h #pragma once # ...
- Redis并发锁控制
为了防止用户在页面上重复点击或者同时发起多次请求,请求处理需要操作redis缓存,这个时候需要对并发边界进行并发锁控制,实现思路: 由于每个页面发起的请求带的token具备唯一性,可以将token作为 ...
- android 初步了解应用Gson 解析Json数据
1,因为没有服务器返回数据,对于Tomcat又懒得去配,所以我直接把数据写死到app中 先写一个实体类,便于操作 /** * 实体类 */ public class Person { int id ; ...
- AngularJs的UI组件ui-Bootstrap分享(七)——Buttons和Dropdown
在ui-Bootstrap中,Buttons控件和Dropdown控件与form表单中的按钮和下拉框名字很像,但实际上这两个控件有新的含义. 先说Buttons,它是一组按钮,用来实现form表单中的 ...
- PyAutoGUI-python版的autoit/AHK
简单介绍各个图形界面自动操作的python库,类似按键精灵\autoit\ahk(autohotkey)等等这些自动化工具.这类python库不是只是用来实现自动游戏之类的程序,业界也用这些库来做GU ...
- php 网页 301 跳转
php 跳转 if('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'] =="http://www.nikemalaysia.co ...
- 安全协议系列(五)---- IKE 与 IPSec(上)
IKE/IPSec 属于网络层安全协议,保护 IP 及上层的协议安全.自上个世纪末面世以来,关于这两个协议的研究.应用,已经非常成熟.协议本身,也在不断地进化.仅以 IKE 为例,其对应的 RFC 编 ...
- Log4J日志管理类使用详解 (转)
一.前言: log4j 是一个开放源码项目,是广泛使用的以Java编写的日志记录包.由于log4j出色的表现, 当时在log4j完成时,log4j开发组织曾建议sun在jdk1.4中用log4j取代j ...