如何在 Mac OS X 上进行原始 IO? (即相当于 Linux 的 O_DIRECT 标志)

问题描述 投票:0回答:3

我一直在谷歌搜索一种在 macOS 下进行原始(有时称为直接)I/O 的方法。原始 I/O 会关闭操作系统页面缓存,使应用程序能够更直接地访问磁盘。这很有用,因为我正在使用的一些文件结构使用 LRU 页面替换效率不高。实现我们需要的页面替换算法相当简单,但首先我们需要关闭 os x 默认缓冲。我们已经在 Linux 下在打开文件时使用 O_DIRECT 标志完成了此操作。有谁知道如何在 mac os 下关闭页面缓冲吗?

c linux macos
3个回答
19
投票

在阅读了更多手册页后,我终于找到了理想的答案。事实证明,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
    }

5
投票

您可能想使用

madvise
系统调用。 您可以使用
MADV_DONTNEED
MADV_WILLNEED
向内核提示首先刷新哪些页面。 OS X 还支持
mmap
标志
MAP_NOCACHE
,它指示内核首先丢弃生成的页面。


1
投票

您需要使用

open
而不是
fopen
,我相信要真正拥有原始访问权限,您必须直接从 /dev/rdisk? 读取。

© www.soinside.com 2019 - 2024. All rights reserved.