如何确保内存映射文件中的内存页可访问?

6

我正在使用Qt将文件映射到内存页中

QFile::map (qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions)

本质上,这应该是一个mmap系统函数调用。我想知道如何保证即使磁盘上的文件被截断,我也能访问返回的内存。我似乎需要这个功能,因为我正在从磁盘文件中读取数据并希望优雅地处理错误。

if (offset > m_file.size()) 
  // throw an error...
if (m_mappedFile != NULL) return m_mappedFile + offset;

显然,这里存在竞态条件,因为文件大小在检查和访问映射之间可能会发生变化。如何避免这种情况?

只要有一些打开的描述符引用它 - open()mmap(),文件就不会停止存在。即使另一个进程发出remove(),或者您从shell中使用rm删除它。 - xtof pernod
1
@xtofpernaud 是的,你是对的。但如果我截断它,那会修改与文件描述符相关联的文件。 - Johannes Schaub - litb
1
从mmap的man手册中:SIGBUS尝试访问与文件不对应的缓冲区部分(例如超出文件末尾,包括另一个进程截断文件的情况)。如果您的代码可能会出现这种情况,则需要处理SIGBUS。 - xtof pernod
@Ben 是的,你说得对,谢谢;但我在想为什么/何时mmap()一个文件时,其他人可以随时truncate(),可能会丢失数据.. - xtof pernod
1
@FrankOsterfeld我只是希望在文件突然发生外部更改(用户删除或截断文件)的情况下尽可能保持稳定。我知道没有100%的安全性。 - Johannes Schaub - litb
显示剩余5条评论
1个回答

3

来自man mmap

SIGBUS Attempted  access to a portion of the buffer that does not correspond to the file
       (for example, beyond the end of  the  file,  including  the  case  where  another
       process has truncated the file).

因此,您需要为SIGBUS安装信号处理程序(默认情况下会导致程序崩溃)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接