附加到内存映射文件
我不断地附加股票报价文件(整数、长整数、双精度数等)。我使用 mmap 将这个文件映射到内存中。
使新附加的数据可用作内存映射的一部分的最有效方法是什么?
我知道我可以再次打开文件(新文件描述符),然后映射它以获取新数据,但这似乎效率低下。向我建议的另一种方法是以 1mb 块预先分配文件,写入特定位置直到到达末尾,然后将文件截断为 +1mb。
还有其他方法吗?
Boost 对此有帮助吗?
I'm constantly appending to a file of stock quotes (ints, longs, doubles, etc.). I have this file mapped into memory with mmap.
What's the most efficient way to make newly appended data available as part of the memory mapping?
I understand that I can open the file again (new file descriptor) and then mmap it to get the new data but that seems to be inefficient. Another approach that has been suggested to me is to pre-allocate the file in 1mb chunks, write to a specific position until reaching the end then ftruncate the file to +1mb.
Are there other approaches?
Doest Boost help with this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Boost.IOStreams 仅具有固定大小 内存映射文件,所以它对解决您的具体问题没有帮助。 Linux 有一个接口
mremap
,其工作原理如下:然而,这是不可移植的(并且文档很少)。 Mac OS X 似乎没有
mremap
。在任何情况下,您都不需要重新打开文件,只需
munmap
并再次mmap
即可:预分配方案在这里可能非常有用。请务必跟踪文件的实际长度并在关闭之前再次截断它。
Boost.IOStreams has fixed-size only memory mapped files, so it won't help with your specific problem. Linux has an interface
mremap
which works as follows:This is non-portable, however (and poorly documented). Mac OS X seems not to have
mremap
.In any case, you don't need to reopen the file, just
munmap
it andmmap
it again:A pre-allocation scheme may be very useful here. Be sure to keep track of the file's actual length and truncate it once more before closing.
我知道答案已被接受,但如果我提供答案,也许会对其他人有所帮助。提前分配一个大文件,例如 10 GiB 大小。提前创建其中三个文件,我将它们称为卷。跟踪您最后已知的位置(例如标头、另一个文件等),然后从该点继续追加。如果达到文件的最大大小并且空间不足,请切换到下一个卷。如果没有更多卷,请创建另一个卷。请注意,您可能会提前几个卷执行此操作,以确保不会阻止您的追加等待创建新卷。这就是我们在 DVR 系统中存储连续传入视频/音频以进行监控的工作中实现它的方式。我们不会浪费空间来存储视频剪辑的文件名,这就是为什么我们不使用真正的文件系统,而是使用平面文件,我们只跟踪偏移量、帧信息(fps、帧类型、宽度/高度等) )、记录时间和摄像机通道。对于您来说,存储空间对于您所做的工作来说是便宜的,而您的时间却是无价的。所以,提前抢够你想要的东西。您基本上是在实现自己的文件系统,并根据您的需求进行了优化。通用文件系统提供的需求与我们在其他领域的需求不同。
I know the answer has already been accepted but maybe it will help someone else if I provide my answer. Allocate a large file ahead of time, say 10 GiB in size. Create three of these files ahead of time, I call them volumes. Keep track of your last known location somewhere like in the header, another file, etc. and then keep appending from that point. If you reach the maximum size of the file and run out of room switch to the next volume. If there are no more volumes, create another volume. Note that you would probably do this a few volumes ahead to make sure not to block your appends waiting for a new volume to be created. That's how we implement it where I work for storing continuous incoming video/audio in a DVR system for surveillance. We don't waste space to store file names for video clips which is why we don't use a real file system and instead we go flat file and we just track offsets, frame information (fps, frame type, width/height, etc), time recorded and camera channel. For you storage space is cheap for the kind of work you are doing, whereas your time is invaluable. So, grab as much as you want to ahead of time. You're basically implementing your own file system optimized for your needs. The needs that general-use file systems supply aren't the same needs that we need in other fields.
查看 mremap 的手册页 应该是可能的。
Looking at man page for mremap it should be possible.
我的 5 美分,但它们更针对 C 语言。
制作普通文件,但 mmap 大小很大 - 例如文件是 100K,但 mmap 1GB 或更多。然后您就可以安全地访问不超过文件大小的所有内容。超过文件大小的访问将导致错误。
如果您使用的是 32 位操作系统,请不要使 mmap 太大,因为它会占用您的地址空间。
My 5cents, but they are more C specific.
Make normal file, but mmap huge size - e.g file is say 100K, but mmap 1GB or more. Then you can safely access everything up to file size. Access over file size will result in error.
If you are on 32bit OS, just dont make mmap too big, because it will eat your address space.
如果您在 Windows 上使用
boost/iostreams/device/mapped_file.hpp
:如果读取映射对象打开,
boost::filesystem::resize_file
会抛出异常,因为缺乏共享权限。相反,使用 windows-api 调整光盘上的文件大小,并且读取的
mapped_file
仍然可以打开。If you're using
boost/iostreams/device/mapped_file.hpp
on windows:boost::filesystem::resize_file
throws an exception if a reading mapping object is open, due to lack of sharing privileges.Instead, use windows-api to resize the file on the disc, and the reading
mapped_file
s can still be open.