|
Boost Users : |
Subject: Re: [Boost-users] [Interprocess] [file_mapping] is there any way to avoid writing a modified file to disc?
From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2011-12-07 11:43:22
El 07/12/2011 16:21, Thorsten Ottosen escribió:
> Den 07-12-2011 16:13, Ion Gaztañaga skrev:
>> El 07/12/2011 14:44, Dean Michael Berris escribió:
>>> Actually, I just checked the docs: it seems you want the
>>> 'copy_on_write' mode which combines PROT_WRITE|PROT_READ and
>>> MAP_PRIVATE. This allows you to make changes in place to the memory
>>> region without having the changes reflected to the original file.
>>
>> Yes, copy_on_write should work. When a page is modified the OS creates a
>> new page for you but other process sees your changes (well, I guess they
>> can end in the page file).
>
> Well, at least with 1.45 I cannot get it to work.
Can you send me an example? (Are you using managed_mapped_file or
mapped_region?) Maybe the bug it still there.
> I also speculate if its actually any faster, since I need to change
> every single byte in the memory region (I'm decrypting).
>
> My understanding of these OS features are weak, but my mental model of
> it is that
>
> //Create a file mapping
> file_mapping m_file( file.c_str(), boost::interprocess::read_only );
>
> //Map the whole file with read-write permissions in this process
> mapped_region region( m_file, boost::interprocess::read_only );
>
> //Get the address of the mapped region
> const char* addr = static_cast<char*>(region.get_address());
> const size_t size = static_cast<int>(region.get_size());
>
> makes the whole file avaiable as one big memory segment.
Yes, but in this case modifying the data should segfault (you are
mapping the memory as read-only, trying to write it will make your MMU
act). You can do this (at least this works in the latest version):
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <cstddef> //std::size_t
#include <cassert>
#include <fstream>
#include <cstring> //memset
#include <cstdlib> //remove
static char zeros [256];
int main()
{
using namespace boost::interprocess;
//Create a file with zeros
std::remove("myfile");
{
std::ofstream f("myfile", std::ios_base::binary);
f.write(&zeros[0], sizeof(zeros));
}
{
file_mapping fmapping("myfile", read_only);
mapped_region mregion(fmapping, copy_on_write);
char* const orig_addr = static_cast<char*>
(mregion.get_address());
const std::size_t orig_size =
static_cast<int>(mregion.get_size());
char* addr = orig_addr;
std::size_t size = orig_size;
///File is not modified, but we
while(size--){
assert(*addr == 0);
*addr++ = 1;
}
assert(*orig_addr != 0);
//The OS discards changes
}
{
std::ifstream f("myfile", std::ios_base::binary);
f.read(&zeros[0], 1);
assert(zeros[0] == 0);
}
std::remove("myfile");
//
return 0;
}
> It seems to me that the OS must do something to write changed data to
> disc (that is, there is an implicit flush() in one of the destructors).
> Hence I assumed that it would be possible to avoid this flush, leaving
> the file intact.
In theory, when mapping something copy on write, the OS will discard
modified pages. The original file/shared memory shoud never be modified.
Ion
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net