您的位置:首页 > 运维架构 > Linux

字符串从内存写入到磁盘的过程中到底发生了什么(一)

2016-08-10 10:45 579 查看
有个朋友问我说写的挺好,但是不知道怎么实践。我本来说看看Sqlite源码,但想想对于新手直接看源码还不现实的。和几个朋友讨论了下这个问题,发现了一个野鸡网站,里面有一个关于I/O存储的题。看了下题目设计和评测规则,挺靠谱的,新手去写写这个题对I/O优化很应该能有很大提升。这里是链接,大家可以去看看,感觉这题好好做做再去看Sqlite,就没有那么困难了。

相信每个程序员都往磁盘写过数据,然而写磁盘的过程到底发生了什么呢?这次我就来带领大家来一次大冒险。

示例代码

这段代码的作用就是往一个
data
文件中写入
Hello, World!
。我们就以这段C代码和Linux系统(内核版本4.X)为例子来讲解。

#include <stdio.h>

int main() {
FILE* f = fopen("data", "w+");
fputs("Hello, World!", f);
fclose(f);
}


API到系统调用

编写应用程序一般是调用API(应用编程接口)来完成。虽然API这个词已经被滥用了,但最初API的思想在于封装系统调用(System Call),让系统调用对用户透明。因为系统调用既然叫系统调用,就说明是和操作系统相关的。也就说,使用A系统的系统调用的程序,到了B系统可能就无法编译了。

然而归根结底,当你的应用程序需要使用到操作系统功能时候,无论调用什么API,最后还是需要系统调用。当然,写磁盘这件事是由操作系统来管理的,所以操作系统也提供了一组对应的系统调用。



以文中的例子来说,应用程序调用了API
fputs
,接着
fputs
会调用系统调用
write
来交由操作系统来完成接下来的工作。

顺便一提,fopen调用的open系统调用,而fclose调用的是close系统调用。

系统调用到文件系统

Linux系统为了兼容多种操作系统,把各种文件系统抽象成VFS(Virtual File System, 虚拟文件系统),VFS会提供一组未实现的接口,然后不同的文件系统提供不同的实现。比如我们之前提到的
write
系统调用,会调用VFS的
sys_write
接口,然后会调用具体文件系统的对应的
write
方法。



文件系统

一段字符串到了文件系统就比较复杂了,因为不仅仅要记录字符串本身,还需要记录一些元信息(属于哪个文件,在哪个目录等等)。这里以最流行的EXT4文件系统为例来进行讲解。

首先一块物理磁盘可以分多个区,每个区对应一个文件系统。EXT4文件系统中又分了多个group,每个group中有:

super block:记录inode和data block的总量和使用量等信息

inode:存放文件的元信息以及文件内容所在data block位置

data block:存放文件内容,一个文件可能会使用多个data block



那么以本文中例子来说,就是在当前目录创建了一个文件名为
data
的文件。对应的磁盘操作有添加一个inode用于记录该
data
文件,然后把该inode关联到其所在的文件夹中,这样就可以通过该文件夹找到该文件了。接着
data
文件对应inode中会记录一个data block,在写入完成后,该data block的内容为
Hello, World


不过,文件系统也只是让一个简单的写入,变成了一系列的磁盘写入,但是不管是inode也好,data block也好,说到底还是存储在硬盘,其本质还是往磁盘写入一些数据。

Block I/O

文件系统又是调用什么接口写磁盘的呢?在Linux中就是通过Block I/O来完成的。

在Linux中,提供了Block I/O层,用于封装对Block设备操作。Block设备就是能够随机读写一个固定块数据的设备,比如我们熟悉的HDD硬盘,HDD硬盘的一个扇区(Sector)就是其最小读写单位。一般HDD磁盘的最小读写单位(也就是扇区)为512字节。也就是说,在HDD磁盘上,写入10字节和写入512字节都是对应一次Block I/O。

文件系统会把需要待写入的数据转化为Block I/O调用。由于Block设备一次写入和寻址是比耗时的,所以Block I/O并不会立即写入,而是会缓存在队列中,进行一轮合并和重排之后再进行操作,达到优化性能的目的。

最后,Block I/O通过调用硬件设备的驱动程序,就完成了整个写入的过程。

总结

我们简单地讨论了一次写入的大体流程,还有诸多细节留待后续讲解,这里有个图片可以参考Linux I/O栈的全景

所以一个简单的文件写入接口,后面居然还有这么多事情。然而这一切,就在你一眨眼的瞬间就完成了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  磁盘 linux
相关文章推荐