linux - madvise(___, ___, MADV_DONTNEED) 是否指示操作系统延迟写入磁盘?

标签 linux linux-kernel kernel shared-memory mmap

假设,假设我想对一个可能非常大的文件执行顺序写入。

如果我 mmap() 一个巨大的区域并在整个区域上进行 madvise(MADV_SEQUENTIAL),那么我可以以相对有效的方式写入内存。我已经开始工作了。

现在,为了在我写作时释放各种操作系统资源,我偶尔会在已经写入的小块内存上执行 munmap()。我担心的是 munmap() 和 msync() 会阻塞我的线程,等待数据以物理方式提交到磁盘。我根本不能放慢我的作家的速度,所以我需要找到另一种方法。

在已经写入的小内存块上使用 madvise(MADV_DONTNEED) 会更好吗?我想告诉操作系统将该内存延迟写入磁盘,而不是阻止我的调用线程。

关于 madvise() 的联机帮助页有这样的说法,这是相当含糊的:

MADV_DONTNEED
Do  not expect access in the near future.  (For the time being, the 
application is finished with the given range, so the kernel can free
resources associated with it.)  Subsequent accesses of pages in this
range will succeed, but will result either in re-loading  of the memory
contents from the underlying mapped file (see mmap(2)) or
zero-fill-on-demand pages for mappings without an underlying file.

最佳答案

不!

为了你好,远离MADV_DONTNEED。 Linux 不会将此视为在写回页面后将其丢弃的提示,而是立即将其丢弃。这不被视为错误,而是经过深思熟虑的决定。

具有讽刺意味的是,原因是非破坏性 MADV_DONTNEED 的功能已经由 msync(MS_INVALIDATE|MS_ASYNC) 给出,MS_ASYNC另一方面不启动 I/O(事实上,它什么都不做,因为脏页写回工作正常),fsync 总是阻塞,sync_file_range 可能会阻止如果你超过了一些模糊的限制并且被文档认为是“极其危险的”,不管那是什么意思。

无论哪种方式,您都必须 msync(MS_SYNC),或 fsync(均阻塞),或 sync_file_range(可能阻塞)后跟 fsync,否则您MADV_DONTNEED而丢失数据。如果您无法承受可能的阻塞,您别无选择,遗憾的是,只能在另一个线程中执行此操作。

关于linux - madvise(___, ___, MADV_DONTNEED) 是否指示操作系统延迟写入磁盘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14968309/

相关文章:

c++ - 比较两个 DRIVER_OBJECT 是否相等?

c - 在 Linux 内核中从 sk_buff 和 inode 获取 PID

java - 部署spring boot应用程序的正确方法是什么

linux - 使用linux计算两个日期之间的时间差

与设备通信的 Linux 程序

linux - 如何查找不同组和用户拥有的所有服务/应用程序

linux - awk、分割并打印一系列列

python - Python系统的基准测试系统性能

c - 内核模块无法在某个语句之后执行语句

Linux 内核配置官方文档