c++中的内存映射二进制日志

Memory mapped binary logging in C++

本文关键字:二进制 日志 映射 内存 c++      更新时间:2023-10-16

我需要获取一个结构体并将其转储到一个文件中以供以后使用。它需要越快越好

在尝试了各种解决方案后,我得出的结论是,memcpy()到内存映射(具有巨大的页面)文件是解决问题的最快解决方案。有没有更好的方法?

我已经尝试过异步日志,但它)最多和同步内存映射解决方案一样快2.)有额外线程的额外开销(我对资源也有限制:)

下面是一个使用Boost的示例。进程间:

#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <fstream>
#include <string>
namespace ip = boost::interprocess;
struct example {
   int data;
   // etc.
};
const char * filename = "/path/to/file";
int main () {
   // Remove existing mapping
   ip::file_mapping::remove (filename);
   // Create file
   std::filebuf fb;
   fb.open(filename, std::ios_base::in | std::ios_base::out
                          | std::ios_base::trunc | std::ios_base::binary);
   fb.pubseekoff (sizeof (example)-1,  std::ios_base::beg);
   fb.sputc (0);
   // Map to file
   ip::file_mapping mapping (filename, ip::read_write);
   // map a region
   ip::mapped_region region (mapping, ip::read_write);
   // Get mapped address
   void *addr = region.get_address( );
   // copy struct to file
   example ex;
   memcpy (addr, &ex, sizeof (example));
   // flush to disk
   region.flush ();
}

要获取数据,请以相同的方式映射到文件(尽管可能只有只读访问)。这里可能会杀死您的是磁盘刷新,这可能需要一段时间。

理想情况下,您应该尝试映射文件版本和Tanzer's Answer中的简单iostream版本。在您的目标平台上测量两者的性能,并选择最佳的一个。

您可以使用ifstream和ofstream类将您的对象以二进制形式写入文件。

struct anyobj;
ofstream ofs("file.bin",ios::binary);
ofs.write ((char*) & anyobj , sizeof(anyobj));

然后读

struct anyobj2;
ifstream ifs ("file.bin", ios::binary);
ifs.read((char*) & anyobj2 , sizeof(anyobj2));

但是您应该注意不同的系统(可移植性)和编译器(不同的填充策略)等情况。