简体   繁体   English

附加到内存映射文件

[英]appending to a memory-mapped file

I'm constantly appending to a file of stock quotes (ints, longs, doubles, etc.). 我不断附加股票报价(整数,多头,双打等)。 I have this file mapped into memory with mmap. 我用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. 我知道我可以再次打开文件(新文件描述符),然后mmap它来获取新数据,但这似乎是低效的。 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. 我建议的另一种方法是以1mb块预先分配文件,写入特定位置直到到达结尾然后将文件ftruncate为+ 1mb。

Are there other approaches? 还有其他方法吗?

Doest Boost help with this? Doest Boost对此有何帮助?

Boost.IOStreams has fixed-size only memory mapped files , so it won't help with your specific problem. Boost.IOStreams只有固定大小的内存映射文件 ,所以它对你的具体问题没有帮助。 Linux has an interface mremap which works as follows: Linux有一个接口mremap ,其工作方式如下:

void *new_mapping = mremap(mapping, size, size + GROWTH, MREMAP_MAYMOVE);
if (new_mapping == MAP_FAILED)
    // handle error
mapping = new_mapping;

This is non-portable, however (and poorly documented). 然而,这是不可携带的(并且记录不完整)。 Mac OS X seems not to have mremap . Mac OS X似乎没有mremap

In any case, you don't need to reopen the file, just munmap it and mmap it again: 在任何情况下,您都不需要重新打开文件,只需将其munmap并再次mmap

void *append(int fd, char const *data, size_t nbytes, void *map, size_t &len)
{
    // TODO: check for errors here!
    ssize_t written = write(fd, data, nbytes);
    munmap(map, len);
    len += written;
    return mmap(NULL, len, PROT_READ, 0, fd, 0);
}

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. 确保跟踪文件的实际长度并在关闭之前再次截断它。

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. 提前分配一个大文件,比如说大小为10 GiB。 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. 这就是我们在DVR系统中用于存储连续传入视频/音频以进行监视的方法。 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. 我们不会浪费空间来存储视频剪辑的文件名,这就是为什么我们不使用真正的文件系统,而是我们去平面文件,我们只是跟踪偏移,帧信息(fps,帧类型,宽度/高度等) ),时间记录和相机频道。 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的手册页应该是可能的。

My 5cents, but they are more C specific. 我的5,但他们更具C特异性。 Make normal file, but mmap huge size - eg file is say 100K, but mmap 1GB or more. 制作普通文件,但mmap巨大 - 例如文件说100K,但mmap 1GB或更多。 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. 如果你使用的是32位操作系统,只是不要让mmap太大,因为它会占用你的地址空间。

If you're using boost/iostreams/device/mapped_file.hpp on windows: 如果你在windows上使用boost/iostreams/device/mapped_file.hpp

boost::filesystem::resize_file throws an exception if a reading mapping object is open, due to lack of sharing privileges. 如果读取映射对象由于缺少共享权限而打开,则boost::filesystem::resize_file会引发异常。 Instead, use windows-api to resize the file on the disc, and the reading mapped_file s can still be open. 相反,使用windows-api调整光盘上的文件大小,读取mapped_file仍然可以打开。

bool resize_file_wapi(string path, __int64 new_file_size) //boost::uintmax_t size
{
    HANDLE handle = CreateFile(path.c_str(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, 0);
    LARGE_INTEGER sz;
    sz.QuadPart = new_file_size;

    return handle != INVALID_HANDLE_VALUE
    && ::SetFilePointerEx(handle, sz, 0, FILE_BEGIN)
    && ::SetEndOfFile(handle)
    && ::CloseHandle(handle);
}

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

相关问题 在内存映射文件中写入内存映射文件 - writing to memory mapped file while it is memory-mapped 遍历boostedapped_region /内存映射文件? - Iterate through boost mapped_region/memory-mapped file? WinAPI:是否需要在可执行的内存映射文件上调用FlushInstructionCache? - WinAPI: Is it needed to call FlushInstructionCache on an executable memory-mapped file? 从函数返回boost :: interprocess内存映射文件? - Returning boost::interprocess memory-mapped file from function? 如果进程是SIGKILLed,OS(POSIX)是否刷新内存映射文件? - Does the OS (POSIX) flush a memory-mapped file if the process is SIGKILLed? 是否可以在2GB +文件上创建较小的内存映射视图? - Is it possible to create smaller memory-mapped views on a 2GB+ file? 如何使用Boost的`mapped_file_sink`类刷新内存映射文件? - How to flush memory-mapped files using Boost's `mapped_file_sink` class? 如何确保内存映射文件可以访问内存页? - How can I ensure that a memory-mapped file keeps the memory pages accessible? 使用Win32 / WINAPI通过内存映射文件传输数据 - Transferring data through a memory-mapped file using Win32/WINAPI 我是否需要将类型设为 POD 以使用内存映射文件持久化它? - Do I need to make a type a POD to persist it with a memory-mapped file?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM