【发布时间】:2011-10-19 15:25:47
【问题描述】:
我正在将一些代码从 AIX 移植到 Linux。部分代码使用shmat() system call 创建新文件。在可写模式下与SHM_MAP 一起使用时,可以将文件扩展至超出其原始长度(在我的情况下为零):
当一个文件被映射到一个段上时,通过访问该段来引用该文件。内存分页系统会自动处理物理 I/O。超出文件末尾的引用会导致文件以页面大小的增量进行扩展。文件不能扩展到下一个段边界之外。
(AIX 中的“段”是 256 MB 的地址空间块,而“页”通常是 4 KB。)
我希望在 Linux 上做的事情如下:
- 保留一大块地址空间(它不必像 256 MB 一样大,这些不是那么大的文件)
- 设置页面保护位,以便在第一次访问之前未触及的页面时生成段错误
- 在页面错误时,清除“导致页面错误”位并为页面分配已提交的内存,从而允许导致页面错误的写入(或读取)继续进行
- 关闭共享内存区域后,将修改后的页面写入文件
我知道我可以在 Windows 上使用VirtualProtect 函数、PAGE_GUARD 内存保护位和structured exception handler 执行此操作。在Linux上做同样的相应方法是什么?是否有更好的方法在 Linux 上实现这种写时扩展功能?
我已经考虑过了:
- 使用
mmap()和一些固定的大尺寸,但我不知道应用程序代码写入了多少文件 - 分配了一个很大的匿名共享内存区域,但我还是不知道该区域已经写入了多少
-
mmap()本身似乎没有提供任何工具来扩展支持文件的长度
当然,我希望只对应用程序代码进行少量更改。
【问题讨论】: