Search code examples
c++boostmemory-mapped-files

flush on boost::mapped_region superfluous?


I am experimenting with boost::interprocess::mapped_regions for fast reading/writing data.

My understanding is that once mapped regions points to a memory mapped object(in my case a boost::interprocess::file_mapping), any writes into the mapped_region will be reflected into the actual file only after I flush the mapped_region.

In the following code snippet, I am :

  • creating a 100 MB file on disk, filling it with all 'B's then
  • creating a file mapping on this file in disk then
  • creating a mapped region from the file mapping then
  • modifying the mapped region data to all 'A' s then
  • flushing the mapped region so that the data is reflected on the actual disk

    const size_t SIZE = 1024 * 1024 * 100;
    
    const char * PATH = "C:/1.txt";
    
    void CreateFile()
    {
        auto ptr = std::unique_ptr<char[]>(new char[SIZE]);
        memset(ptr.get(), 'B', SIZE);
    
        ofstream fs(PATH, ios::binary);
        fs.write((char *)ptr.get(), SIZE);
    }
    
    int main()
    {
         CreateFile();
    
         file_mapping fm(PATH, read_write);
    
         mapped_region ms(fm, read_write, 0, SIZE);
    
         memset(ms.get_address(), 'A', SIZE);
    
         ms.flush(0, SIZE, false);
    
         int x = 10;
    }
    

Ideally only after I call ms.flush() should the changes be reflected in 1.txt. But soon after calling memset, the contents of 1.txt change to all 'A' s.

Why is this so?


Solution

  • On Windows when you modify the memory you are modifying the file. The OS guarantees any reader of the file will see your changes at once.

    The data isn't immediately written to disk; that would be impossibly expensive. But any read of the file can be, and is, satisfied from the copy in memory.

    And in general I believe the OS is free to flush to disk at any time; the explicit flush() ensures it happens, but it may already have been done.