【问题标题】:Writing to memory and to disk simultaneously同时写入内存和磁盘
【发布时间】:2012-10-25 16:42:18
【问题描述】:

我正在开发一个应用程序,该应用程序需要在内存中保留一定时间 t 的数据(可配置),并在磁盘上的持久存储中保留另一时间 t2 的数据.这背后的原因是,经常询问的数据将存储在内存中并更快地检索,而较旧的、不经常使用的用户数据将存储在磁盘上并可以检索。

问题是:我不能简单地写入内存,然后在时间 t 之后将内存缓冲区的全部内容复制到磁盘,就像应用程序崩溃一样,最近的数据存储在内存中会迷路。因此,每次收到新数据时,我都需要将其同时存储在内存和磁盘中。

我的问题是,有没有一种有效的方法将内存中的缓冲区镜像到磁盘的一部分?我正在寻找一种比在每次数据更新时先写入内存然后写入磁盘更有效的方法。

【问题讨论】:

  • mmap() 应该是你的朋友,我相信:en.wikipedia.org/wiki/Mmap 这适用于 POSIX 系统(例如 Linux 和 Mac。)如果你在 Windows 上,MapViewOfFile 应该提供类似的功能:@987654322 @
  • @Nikos Chantziaras:如果我在 amiga 上呢?
  • 您是只担心应用程序崩溃(操作系统缓冲区仍然有效),还是计算机崩溃?
  • 谢谢@Nikos Chantziaras - 正是我需要的。
  • "如果应用程序崩溃,存储在内存中的最新数据将会丢失。"没有解决办法

标签: c++ c memory


【解决方案1】:

您可以对文件进行内存映射,unix 和 windows 系统都支持这一点(但使用不同的 API)。之后,您可以简单地写入该内存位置,并在需要时进行同步。

【讨论】:

    【解决方案2】:

    Boost Memory-Mapped Files

    mapped_file_source、mapped_file_sink 和 mapped_file 类提供对 WindowsPOSIX 系统上的内存映射文件的访问

    LIVE DEMO

    #include <boost/iostreams/device/mapped_file.hpp>
    #include <boost/range/istream_range.hpp>
    #include <boost/range/algorithm.hpp>
    #include <boost/range/irange.hpp>
    #include <iostream>
    #include <iterator>
    #include <fstream>
    #include <string>
    
    using namespace std;
    using namespace boost;
    using namespace boost::iostreams;
    
    int main()
    {
        string filename("test.mmap");
        { // Prepare file
            ofstream f(filename);
            copy(irange(0,255), ostreambuf_iterator<char>(f));
        }
        { // Work with memory mapped file
            mapped_file mm(filename);
            fill(mm, 0); // Works as range
            char *data=mm.data(); // Or as raw memory pointer
            copy("String in memory", data); // Copy to raw memory
        }
        { // print file contents
            ifstream f(filename);
            copy(istream_range<char>(f), ostream_iterator<char>(cout));
        }
    }
    

    【讨论】:

      【解决方案3】:

      最好的方法是先写入内存再写入磁盘。如果内存已满,请在写入内存之前删除最少使用的项目。

      另一种技术是有一个单独的执行线程将新项目写入磁盘。线程将唤醒,检查新项目并将其写入磁盘。这些项目将被标记为“不是新的”。然后线程重新进入睡眠状态。睡眠持续时间应该足够长,以便在内存中存储多条记录,但要足够快,以便在断电或崩溃期间丢失更少的记录。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-09
        • 1970-01-01
        • 2012-04-13
        • 2018-11-07
        • 2011-01-03
        相关资源
        最近更新 更多