Linux系统编程——文件IO——写回实验
1.目的
验证 页缓存 和 写回机制
2.方法
分别用 write,mmap 写入文件,写入后进行sleep,用cat命令查看文件是否有数据,然后断电,重启后查看文件是否有数据。
为了方便测试将 回写时间阈值调整为 50000ms
echo 50000 > /proc/sys/vm/dirty_writeback_centisecs
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#define WRITE_TEST
int main()
{
int fd;
fd = open("./tmp", O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd < 0) {
perror("open");
return -1;
}
const char *str = "hello world";
#ifdef WRITE_TEST
write(fd, str, strlen(str));
close(fd);
#else
char *ptr;
int file_size = 25;
if (ftruncate(fd, file_size) < 0) {
perror("ftruncate");
return -1;
}
ptr = mmap(NULL, file_size, PROT_READ | PROT_WRITE , MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
return -1;
}
close(fd);
strcpy(ptr, str);
munmap(ptr, file_size);
#endif
return 0;
}
3. 结果
重启前另一个进程读文件 | 重启后进程读文件 | 重启前查看文件元信息之文件大小 | 重启后查看元信息 | |
---|---|---|---|---|
write | 有数据 | 无数据 | 25字节 | 0字节 |
mmap | 有数据 | 无数据 | 25字节 | 0字节 |
3.1 为什么重启前文件有数据,重启后无数据
因为进程读取的数据来自页缓存,页缓存被测试程序写入了数据,但数据没有写回,因为系统有足够的物理内存且未超过写回阈值,
重启后,读文件,文件数据加载到页缓存,程序从页缓存读数据,但是文件本身没有数据,所以显示为空。
文件元数据的情况同上。
4. 使用直接IO测试
write 加上 O_SYNC ,能真实写入,
另外发现 O_SYNC的程序 不会让 其他 页缓存也写回。
O_DIRECT 报参数错误,应该由于是写入数据没有块对齐
mmap:
msync + MS_ASYNC : 不能保证写入
msync + MS_SYNC : 能保证写入
5. 结论
close 不能保证 数据真实写入文件,因为 struct file * 只是 进程和文件的会话,和文件无关,即使一个进程结束会话,其他进程也可能再开启会话,所以 内存中的文件(页缓存)必须保留。
munmap 不能保证 数据真实写入文件,因为 munmap 只是 结束页缓存 映射到一个进程的虚拟空间,于 内存中文件(页缓存)无关。
其他进程能从文件中读取数据,不能保证 数据真实写入文件,因为进程读写文件,是和内存中的文件(页缓存)打交道,与磁盘上的文件无关。
只有 O_SYNC 或 msync + MS_SYNC 或 sync() 等,才能让 脏块加入 IO队列,让pdflush完成写入磁盘。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?