硬件视角:“持久化” 的层层抽象
用户 (应用程序) 视角:对象 + API
C:\Program Files\...
/etc/apt/sources.list
/bin/bash
...中间的部分:文件系统
理解 “文件系统” 的设计
我都有吃饱穿暖了,还要什么计算机?
“开机” 后操作系统中应该有的对象
没问题!我们已经讲过 1-bit 的存储了
今天的系统中有不止一个程序
文件系统:设计目标
磁盘 (I/O 设备) = 一个可以读/写的字节序列
std::vector<char>
文件系统 API: 虚拟磁盘管理
文件系统 = “虚拟磁盘名” 到 “虚拟磁盘对象” 的映射
局部性来帮忙!
.
└── 学习资料
├── .学习资料(隐藏)
├── 问题求解1
├── 问题求解2
├── 问题求解3
└── 问题求解4
树总得有个根结点
C:\
“C 盘根目录”C:\Program Files\
, C:\Windows
, C:\Users
, ...D:\
“D 盘根目录”D:\学习资料\
A:\
, B:\
?game.iso
一度非常麻烦……/
。其他没有了/
和 exFAT)mount
命令 “挂载” 到一个目录上/
, /home
, /var
可以是独立的磁盘如何 mount 一个文件?
This standard (FHS) enables:
这个简单
rm -rf
会遍历目录,逐个删除 (试试 strace)count
个目录项 (ls, find, tree 都使用这个)需求:系统中可能有同一个运行库的多个版本
libc-2.27.so
, libc-2.26.so
, ...libc.so.6
”硬连接:允许一个文件被多个目录引用
小知识:其实所有的文件都是硬连接 (ls -i
查看)
软链接:在文件里存储一个 “跳转提示”
ln -s
创建软链接
symlink
系统调用软链接可以随意创建 (当前可能不合法;但未来可能合法)
允许多次间接链接
可以创建软连接的硬链接 (因为软链接也是文件)
ls -i
可以看到 符号链接成环?
ln -s . a
working/current directory
pwd
命令或 $PWD
环境变量可以查看chdir
系统调用修改/bin/cd
问题:线程是共享 working directory, 还是各自独立持有一个?
文件:虚拟的磁盘
文件描述符:进程访问文件 (操作系统对象) 的 “指针”
open
/pipe
获得使用 open 打开一个文件后
MAP_SHARED
将文件映射到地址空间中MAP_PRIVATE
创建一个 copy-on-write 的副本void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset); // 映射 fd 的 offset 开始的 length 字节
int munmap(void *addr, size_t length);
int msync(void *addr, size_t length, int flags);
小问题:
SIGBUS
...文件的读写自带 “游标”,这样就不用每次都指定文件读/写到哪里了
例子
read(fd, buf, 512);
- 第一个 512 字节read(fd, buf, 512);
- 第二个 512 字节lseek(fd, -1, SEEK_END);
- 最后一个字节mmap, lseek, ftruncate 互相交互的情况
length
= 2 MiB)SEEK_SET
)在任何时刻,写入数据的行为是什么?
文件描述符在 fork 时会被子进程继承。
父子进程应该共用偏移量,还是应该各自持有偏移量?
offset
存储在哪里考虑应用场景
write
的原子性 ✅操作系统的每一个 API 都可能和其他 API 有交互 😂
O_APPEND
方式打开的文件,偏移量永远在最后 (无论是否 fork)这也是 fork 被批评的一个原因
fork()
in the road本次课内容与目标
Takeaway messages