第九十三章:tmpfs
斩灵期涉及内核源码:
一
林小源穿过一片薄雾,走进了一个奇异的领域。这里的地面是半透明的,脚下能看到流动的光点——那是内存中的数据在涌动。
"这是什么地方?"林小源蹲下身,手掌贴在地面上,感受到一股温热的脉动。
"tmpfs。"一个年轻的声音从身后传来。林小源转身,看到一个轻盈的身影——它的身体几乎是透明的,只有轮廓在微微发光。"内存文件系统。"
"内存文件系统?"林小源站起来,"你的数据不存磁盘?"
tmpfs 摇了摇头,透明的发丝在空中飘动:"不用磁盘。我所有的数据都在 RAM 里——你脚下的每一个光点,都是一个内存页。读写速度是内存速度,比磁盘快几十倍。"
林小源踩了踩地面,确实感觉比之前走过的 ext4 和 btrfs 的领地要轻盈得多。"那你岂不是……很快?"
"非常快。"tmpfs 微微一笑,"但有一个代价——重启之后,一切都会消失。我不持久。"
"消失?"林小源有些惊讶,"那谁会用你?"
"很多人。"tmpfs 指了指远处,"看到那边的 /tmp 目录了吗?那是我的领地。程序运行时产生的临时文件,放在那里最合适——用完就扔,重启自动清理。还有 /run,存放 PID 文件和 socket 文件;/dev/shm,POSIX 共享内存。"
二
林小源跟着 tmpfs 走在半透明的地面上,忽然注意到前方有一片区域颜色更深,光线更密集。
"那是 swap。"tmpfs 说,"当内存不够用的时候,我可以把一部分数据交换到磁盘上的 swap 分区。这是我和 ramfs 最大的区别。"
"ramfs?"林小源想起了另一个虚拟文件系统。
"ramfs 是我的前辈。"tmpfs 的语气里带着一丝尊敬,"它也是基于内存的文件系统,但它没有大小限制——可以无限增长,直到把所有内存吃光。这很危险。"
"所以你加了限制?"
"对。"tmpfs 说,"我可以设置 size 参数限制最大大小,还可以设置 限制最大 inode 数。而且我可以使用 swap——内存不够时,把冷数据交换出去,腾出空间给热数据。"
林小源蹲下身,仔细观察脚下的光点。有些光点明亮活跃,有些则暗淡缓慢。"这些是在区分冷热数据?"
tmpfs 点头:"内核的页面回收算法会帮我管理。长时间不访问的页面会被交换到 swap,腾出物理内存。"
三
林小源来到 /dev/shm 的入口。这里的光线格外明亮,空气中弥漫着一种奇特的振动——像是多个进程在同时读写同一个区域。
"这是 POSIX 共享内存。"tmpfs 说,"多个进程可以通过读写 /dev/shm 下的文件进行通信。因为数据在内存中,所以速度比通过磁盘文件通信快得多。"
"为什么不直接用管道或 socket?"
tmpfs 沉吟了一下:"管道和 socket 是字节流,适合顺序通信。共享内存是随机访问的——多个进程可以直接读写同一块内存区域的任意位置,适合大数据量的并行处理。"
林小源看着两个光点——两个进程——同时在一块共享区域上读写,数据在它们之间飞速传递。
"但共享内存也有风险。"tmpfs 的语气变得严肃,"没有同步机制的话,多个进程同时写入会导致数据竞争。你需要信号量或者互斥锁来保护共享区域。"
"我记住了。"林小源说。
tmpfs 轻轻挥手,整个领域闪烁了一下:"我虽然虚幻——重启就消失——但在那短暂的存在里,我是最快的文件系统。"
/*
* tmpfs 的特点:
*
* 1. 基于内存
* 数据存储在 RAM 中
* 可以使用 swap
* 重启后丢失
*
* 2. 动态大小
* 不需要预先分配大小
* 随使用量增长
* 受限于 RAM + swap
*
* 3. 快速访问
* 没有磁盘 I/O
* 读写速度 = 内存速度
*
* 4. 支持所有文件操作
* 创建、删除、读写
* 权限、所有者
*
* tmpfs 的用途:
* /tmp — 临时文件
* /run — 运行时数据
* /dev/shm — 共享内存
* /sys/fs/cgroup — cgroup 文件系统
*
* 挂载 tmpfs:
* mount -t tmpfs tmpfs /tmp
* mount -t tmpfs -o size=1G tmpfs /tmp
*/
printf("=== tmpfs — 内存文件系统 ===\n\n");
printf("tmpfs 的特点:\n");
printf(" 基于内存: 数据在 RAM 中\n");
printf(" 动态大小: 随使用量增长\n");
printf(" 快速访问: 内存速度\n");
printf(" 易失性: 重启后丢失\n\n");
printf("--- tmpfs 的用途 ---\n");
printf("/tmp:\n");
printf(" 临时文件\n");
printf(" 程序运行时创建\n");
printf(" 重启后清理\n\n");
printf("/run:\n");
printf(" 运行时数据\n");
printf(" PID 文件\n");
printf(" socket 文件\n\n");
printf("/dev/shm:\n");
printf(" POSIX 共享内存\n");
printf(" 进程间通信\n\n");
printf("--- tmpfs vs ramfs ---\n");
printf("ramfs:\n");
printf(" 基于内存\n");
printf(" 不能使用 swap\n");
printf(" 可以无限增长(危险)\n\n");
printf("tmpfs:\n");
printf(" 基于内存\n");
printf(" 可以使用 swap\n");
printf(" 有大小限制\n\n");
printf("--- 挂载选项 ---\n");
printf("mount -t tmpfs -o size=1G,nr_inodes=100k tmpfs /tmp\n");
printf(" size: 最大大小\n");
printf(" nr_inodes: 最大 inode 数\n\n");
printf("--- tmpfs 的优势 ---\n");
printf("1. 速度: 内存速度访问\n");
printf("2. 简单: 不需要磁盘分区\n");
printf("3. 灵活: 动态大小\n");
printf("4. 清洁: 重启后自动清理\n");#include <stdio.h>
/*
* tmpfs 的特点:
*
* 1. 基于内存
* 数据存储在 RAM 中
* 可以使用 swap
* 重启后丢失
*
* 2. 动态大小
* 不需要预先分配大小
* 随使用量增长
* 受限于 RAM + swap
*
* 3. 快速访问
* 没有磁盘 I/O
* 读写速度 = 内存速度
*
* 4. 支持所有文件操作
* 创建、删除、读写
* 权限、所有者
*
* tmpfs 的用途:
* /tmp — 临时文件
* /run — 运行时数据
* /dev/shm — 共享内存
* /sys/fs/cgroup — cgroup 文件系统
*
* 挂载 tmpfs:
* mount -t tmpfs tmpfs /tmp
* mount -t tmpfs -o size=1G tmpfs /tmp
*/
int main() {
printf("=== tmpfs — 内存文件系统 ===\n\n");
printf("tmpfs 的特点:\n");
printf(" 基于内存: 数据在 RAM 中\n");
printf(" 动态大小: 随使用量增长\n");
printf(" 快速访问: 内存速度\n");
printf(" 易失性: 重启后丢失\n\n");
printf("--- tmpfs 的用途 ---\n");
printf("/tmp:\n");
printf(" 临时文件\n");
printf(" 程序运行时创建\n");
printf(" 重启后清理\n\n");
printf("/run:\n");
printf(" 运行时数据\n");
printf(" PID 文件\n");
printf(" socket 文件\n\n");
printf("/dev/shm:\n");
printf(" POSIX 共享内存\n");
printf(" 进程间通信\n\n");
printf("--- tmpfs vs ramfs ---\n");
printf("ramfs:\n");
printf(" 基于内存\n");
printf(" 不能使用 swap\n");
printf(" 可以无限增长(危险)\n\n");
printf("tmpfs:\n");
printf(" 基于内存\n");
printf(" 可以使用 swap\n");
printf(" 有大小限制\n\n");
printf("--- 挂载选项 ---\n");
printf("mount -t tmpfs -o size=1G,nr_inodes=100k tmpfs /tmp\n");
printf(" size: 最大大小\n");
printf(" nr_inodes: 最大 inode 数\n\n");
printf("--- tmpfs 的优势 ---\n");
printf("1. 速度: 内存速度访问\n");
printf("2. 简单: 不需要磁盘分区\n");
printf("3. 灵活: 动态大小\n");
printf("4. 清洁: 重启后自动清理\n");
return 0;
}道藏笔记
内核启示
tmpfs 是基于内存的文件系统——数据全在 RAM 里,读写速度是内存速度,比磁盘快几十倍。代价是重启之后一切消失,不持久。
它的用途比想象中广。/tmp 是临时文件的家,程序运行时产生的临时数据放那里,用完就扔,重启自动清理。/run 存放 PID 文件和 socket 文件。/dev/shm 是 POSIX 共享内存,多个进程通过读写这里的文件通信,比管道和 socket 快得多——因为数据在内存里,是随机访问的。
跟前辈 ramfs 比,tmpfs 加了大小限制和 swap 支持。ramfs 可以无限增长直到吃光所有内存,很危险。tmpfs 可以设 size 参数限制最大大小,内存不够时还能把冷数据交换到 swap。内核的页面回收算法帮你管理冷热数据。
tmpfs 之试
tmpfs 常被挂到哪个共享内存目录,让数据待在内存里而非普通磁盘文件中?