繁体   English   中英

通过O_DIRECT读取是否首先清除脏页?

[英]Does reading via O_DIRECT flush dirty pages first?

假设我有一个执行以下操作的简单程序:

fdWrite = open("file", O_WRONLY);
fdRead = open("file", O_RDONLY | O_DIRECT);
writeBuffer = <some data>;
write(fdWrite, writeBuffer);
readBuffer = read(fdRead, sizeof(writeBuffer));

我可以保证readBuffer == writeBuffer吗? (显然,当前没有打开此文件的其他fd)

在Linux上进行的一些简单测试似乎表明,是的,在通过O_DIRECT进行读取之前,来自write调用的脏页将被刷新到磁盘上,但是我似乎在任何地方都找不到这种情况。 就我所知,这可能完全是巧合,但我不知道在其他类似POSIX的平台上会发生什么。 我至少想得到一些“确凿的证据”。

你为什么做这个?

这是在应用程序分发要缓存的大文件的上下文中。 收到文件的新部分后,我想验证新部分。 使用O_DIRECT看到两个优点:首先,我不仅要检查是否已正确接收数据,还可以从存储介质中正确检索数据。 没有O_DIRECT我几乎可以保证我只是从页面缓存中获取数据。 为了在不使用O_DIRECT的情况下实现相同的目的,我不得不在Linux上使用不可移植的调用(例如sync_file_range将数据获取到磁盘,然后通过madvise从页面缓存中刷新数据,最后将其读回。 (因为我曾经学过一种很难的方法,即在脏页上用MADV_DONTNEED调用madvise MADV_DONTNEED上是没有问题的)。
但是,如果有人对此有更优雅的建议,我会非常高兴。 :-)

我不仅要检查是否已正确接收数据,还可以从存储介质中正确检索数据。

为此,您需要取消设备完成的缓存。

大多数设备数据缓存相对较小-兆字节而不是千兆字节。[*]如果大文件足够大,则可以执行write()+ fsync(),这将使设备缓存溢出。 然后,使用您的DONTNEED将其从Linux页面缓存中删除。 然后,您可以从设备重新读取()文件。

[*]一些虚拟化环境违反了这一期望。 https://unix.stackexchange.com/questions/420299/why-is-sync-drop-caches-not-dropping-caches/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM