例如,打开一个文件两次,一个 fd 直接 io 写入,另一个 fd 读取页面缓存?
如何定义safe
:从 direct-io fd 写入一些数据,然后期望immediately
从 page-cache fd读取它们
例如,打开一个文件两次,一个 fd 直接 io 写入,另一个 fd 读取页面缓存?
如何定义safe
:从 direct-io fd 写入一些数据,然后期望immediately
从 page-cache fd读取它们
我认为directIO写入文件对于以后对该文件的缓存读取应该是相当安全的,但是读取的性能可能较低(写入的数据未保存在页面缓存中,必须从实际存储中读取)。但确切的代码路径可能取决于使用的文件系统。
这篇文章https://lwn.net/Articles/776801/提到直接 IO 具有失效语义:
至少对于某些文件系统,在页面上执行直接 I/O 读取将强制该页面退出缓存
本书在“写入缓存”部分列出了 3 种写入策略:不写入、直写、回写。直接 I/O 可能是write()
系统调用的“不写”变体。
对单个文件使用多个 fd 是安全的,因为数据由使用 inode 的 FS 代码管理。两个 fd 都将指向同一个 inode。
2013 年邮件列表中有一个线程https://lists.kernelnewbies.org/pipermail/kernelnewbies/2013-July/008660.html和 TLDR 是:
从内核开发人员的角度来看:内核驱动程序保证页面缓存和使用 O_DIRECT 传输的数据之间的一致性。...
- 不要担心页面缓存和使用 O_DIRECT 传输的数据之间的一致性。内核将在 O_DIRECT 写入之后使缓存无效,并在 O_DIRECT 读取之前刷新缓存。
- 使用互斥锁或信号量(或众多选项 [1] 中的任何一个)来防止在使用共享文件的 IPC 期间常见的同步问题。
因此,虽然直接写入会从页面缓存中清除文件的已写入部分,但写入器和读取器之间存在一定的竞争可能性。因此,如果您的读者想要获取更新的数据,则需要互斥锁或其他同步。只有在直接 IO write() 系统调用结束后,页面缓存才会被清除。
有时不建议混合使用:https ://medium.com/databasss/on-disk-io-part-1-flavours-of-io-8e1ace1de017 “不鼓励同时使用 Direct IO 和 Page Cache 打开同一个文件,因为即使数据在页面缓存中,也会对磁盘设备执行直接操作,这可能会导致不希望的结果。 ”