我一直在谷歌搜索一种在 macOS 下进行原始(有时称为直接)I/O 的方法。原始 I/O 会关闭操作系统页面缓存,使应用程序能够更直接地访问磁盘。这很有用,因为我正在使用的一些文件结构使用 LRU 页面替换效率不高。实现我们需要的页面替换算法相当简单,但首先我们需要关闭 os x 默认缓冲。我们已经在 Linux 下在打开文件时使用 O_DIRECT 标志完成了此操作。有谁知道如何在 mac os 下关闭页面缓冲吗?
在阅读了更多手册页后,我终于找到了理想的答案。事实证明,mac os 实际上与 O_DIRECT 具有非常相似的机制,但它不是通过 open 函数,而是通过 fcntl。具体来说,有一个名为 F_NOCACHE 的选项,它允许您打开或关闭特定文件描述符的缓存,这正是我想要的。请参阅 http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man2/fcntl.2.html,了解使用 mac 版本的 fcntl 可以执行的其他操作的完整内容,并解释其确切用途。我希望这个答案能帮助其他人。
http://lists.apple.com/archives/filesystem-dev/2007/Sep/msg00010.html 是一个很好的线程,解释了 F_NOCACHE 标志如何根据您的 mac 操作系统版本号表现。
最终代码(go):
r1, r2, err := syscall.Syscall(syscall.SYS_FCNTL, uintptr(self.file.Fd()), syscall.F_NOCACHE, 1)
if err != 0 {
fmt.Printf("Syscall to SYS_FCNTL failed\n\tr1=%v, r2=%v, err=%v\n", r1, r2, err)
self.Close()
return false
}
您可能想使用
madvise
系统调用。 您可以使用 MADV_DONTNEED
或 MADV_WILLNEED
向内核提示首先刷新哪些页面。 OS X 还支持 mmap
标志 MAP_NOCACHE
,它指示内核首先丢弃生成的页面。
您需要使用
open
而不是 fopen
,我相信要真正拥有原始访问权限,您必须直接从 /dev/rdisk? 读取。