写在前面:这是本系列的第二十二篇。
在存储器之上,操作系统(文件系统)实现了“目录树”结构的文件系统,使我们能以一种直观、自然、有序的方式管理操作系统里数以百万计的持久化对象。
我们已经知道,进程从
execve后的初始状态开始,可以通过mmap改变自己的地址空间,通过fork创建新的进程,再通过execve执行新的程序——我们慢慢已经开始理解“操作系统上的应用生态”并没有魔法了。本讲内容:操作系统还必须给应用程序提供访问操作系统对象的机制。这节课我们学习 UNIX 的“Everything is a file”带来的方便,以及操纵目录和文件系统的 API。
课前反思:Testkit 的修复?
关于前面的 Testkit,其实我还不太会用…
多个.c文件交织在一起,执行顺序不知道,快照机制也没听懂。
没关系,有机会一定要自己琢磨一下怎么用 Test(或者让豆包/Kimi 详细拆解教一下)。在系统编程中,测试框架是重中之重。
回顾:操作系统的对象
- 进程:
- 进程 = 状态机。
- 进程管理 API:
fork,execve,exit。
- 连续的内存段:
- 我们可以把“连续的内存段”看作一个对象,它可以在进程间共享,也可以映射文件。
- 内存管理 API:
mmap,munmap,mprotect,msync。
目录树与存储设备的抽象
存储设备的抽象
- 磁盘 = 块 (字节) 序列:
- 就像一本书,每一页纸存储了数据,支持随机访问(翻到某一页)。
- 文件:虚拟的磁盘:
- 比如
hello.c,a.out… - 在文件里,我们看不到“一页纸”的概念。它被抽象成了一个字节序列(类似
vector<char>)。 - 支持
read,write,lseek,ftruncate等操作。
- 比如
- 新需求:怎么管理系统中众多的文件?总不能每次都全局
find_file_by_name吧?
管理虚拟磁盘:建一个图书馆!
- 信息的局部性:将虚拟磁盘(文件)组织成层次结构。
树状分层索引:利用信息的局部性
. └── 学习资料 ├── . ├── .. ├── .学习资料(隐藏) ├── 问题求解1 ├── 问题求解2 ├── 问题求解3 ├── 问题求解4 └── 操作系统