简体   繁体   English

如何使用Boost的`mapped_file_sink`类刷新内存映射文件?

[英]How to flush memory-mapped files using Boost's `mapped_file_sink` class?

Using the Boost Libraries version 1.62.0 and the mapped_file_sink class from Boost.IOStreams . 使用Boost库版本1.62.0mapped_file_sink从类了Boost.Iostreams

I want to flush the written data to disk at will , but there is no mapped_file_sink::flush() member function. 我要刷新写入的数据到磁盘的意愿 ,但没有mapped_file_sink::flush()成员函数。

My questions are: 我的问题是:

  • How can I flush the written data when using mapped_file_sink ? 使用mapped_file_sink时如何刷新写入的数据?
  • If the above can't be done, why not, considering that msync() and FlushViewOfFile() are available for a portable implementation? 如果上述操作无法完成,为什么不考虑msync()FlushViewOfFile()可移植实现?

If you look at the mapped file support for proposed Boost.AFIO v2 at https://ned14.github.io/boost.afio/classboost_1_1afio_1_1v2__xxx_1_1map__handle.html , you'll notice a lack of ability to flush mapped file views as well. 如果您在https://ned14.github.io/boost.afio/classboost_1_1afio_1_1v2__xxx_1_1map__handle.html上查看对建议的Boost.AFIO v2的映射文件支持,则会注意到也缺乏刷新映射文件视图的功能。

The reason why is because it's redundant on modern unified page cache kernels when the mapped view is identical in every way to the page cached buffers for that file. 原因是因为当映射视图与该文件的页面缓存缓冲区在各个方面都相同时,它在现代统一页面缓存内核上是多余的。 msync() is therefore a no-op on such kernels because dirty pages are already queued for writing out to storage as and when the system decides it is appropriate. 因此,在此类内核上, msync()是禁止操作的,因为在系统认为适当时,脏页已经排队等待写出到存储中。 You can block your process until the system has finished writing out all the dirty pages for that file using good old fsync() . 您可以阻止您的进程,直到系统使用旧的fsync()完成该文件的所有脏页写出为止。

All the above does not apply where (a) your kernel is not a unified page cache design (QNX, NetBSD etc) or (b) your file resides on a networked file system. 以上所有内容均不适用于以下情况:(a)您的内核不是统一的页面缓存设计(QNX,NetBSD等),或者(b)您的文件位于网络文件系统上。 If you are in an (a) situation, best to simply avoid memory mapped i/o altogether, just do read() and write() , they are such a small percentage of OSs nowadays let them suffer with poor performance. 如果您处在(a)情况下,最好是完全避免完全映射到I / O的内存,只需执行read()write() ,它们在当今操作系统中所占的比例很小,因此它们的性能很差。 For the (b) situation, you are highly inadvised to be using memory mapped i/o ever with networked file systems. 对于(b)情况,强烈建议您不要对网络文件系统使用内存映射的I / O。 There is an argument for read-only maps of immutable files only, otherwise just don't do it unless you know what you're doing. 有一个参数仅适用于不可变文件的只读映射,否则除非您知道自己在做什么,否则不要这样做 Fall back to read() and write() , it's safer and less likely to surprise. 退回到read()write() ,它更安全,并且不太可能出现意外。

Finally, you linked to a secure file deletion program. 最后,您链接到一个安全的文件删除程序。 Those programs don't work reliably any more with recent file systems because of delayed extent allocation or copy on write allocation. 由于延迟的扩展区分配或写入时复制,这些程序在最新的文件系统上无法再可靠地工作。 In other words, when you rewrite a section of an existing file, it doesn't modify the original data on storage but actually allocates new storage and points the extents list for the file at the new linked list. 换句话说,当您重写现有文件的一部分时,它不会修改存储中的原始数据,而是实际上分配新的存储,并将文件的扩展区列表指向新的链接列表。 This allows a consistent file system to be recovered after unexpected data loss easily. 这样可以在意外数据丢失后轻松恢复一致的文件系统。 To securely delete data on recent file systems you usually need to use special OS APIs, though deleting all the files and then filling the free space with random data may securely delete most of the data in question most of the time. 为了安全地删除最新文件系统上的数据,您通常需要使用特殊的OS API,尽管删除所有文件然后用随机数据填充可用空间可能会在大多数情况下安全地删除大部分有问题的数据。 Note copy on write filing systems may not release freed extents back to the free space pool for new allocation for many days or weeks until the next time a garbage collection routine fires or a snapshot is deleted. 注意,写文件系统上的副本可能要数天或数周才能将释放的扩展区释放回空闲空间池以进行新的分配,直到下一次垃圾回收例程触发或快照被删除为止。 In this situation, filling free space with randomness will not securely delete the files in question. 在这种情况下,随机填充可用空间将无法安全删除有问题的文件。 If all this is a problem, use FAT32 as your filing system, it's very simple and rewriting data on it really does rewrite the same data on storage (though note that some storage media eg SSDs are highly likely to also not rewrite data, these also write modifications to new storage and garbage collect freed extents later). 如果所有这些都是问题,请使用FAT32作为文件系统,这非常简单,并且在其上重写数据确实可以重写存储上的相同数据(尽管请注意,某些存储介质(例如SSD)也很可能不会重写数据,这些也稍后对新的存储和垃圾收集释放的扩展区进行修改)。

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

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