6

I've done some reading about boost::interprocess::file_lock and it seems to do pretty much what I'm after (support shareable and exclusive locking, and being unlocked if the process crashes or exits).

One thing I'm not sure about though, is what does it do to the file? Can I use for example a file of 0 bytes long? Does boost::interprocess write anything into it? Or is its presence all the system cares about?

I've been using boost::interprocess now for some time to reliably memory map a file and write into it, now I need to go multiprocess and ensure that reads and writes to this file are protected; file_lock does seem the way to go, I just wonder if I now need to add another file to use as a mutex.

Thanks in advance

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
Dave F
  • 973
  • 9
  • 19

1 Answers1

6

what does it do to the file?

Boost does not do anything with the file, it relies on the operating system to get that job done. Support for memory mapped files is a generic capability of a demand-paged virtual memory operating system. Like Windows, Linux, OSX. Memory is normally backed by the paging file, having it backed by a specific file you select is but a small step. Boost just provides a platform-independent adapter, nothing more.

You'll want to take a look at the relevant OS documentation pages to see what's possible and how it is expected to work when you do something unusual. For Linux and OSX you'll want to look at the mmap man pages. For Windows look at CreatefileMapping.

file_lock does seem the way to go

Yes, you almost always need to arbitrate access to the memory mapped file so for example one process will only attempt to read the data when the other process finished writing it. The most suitable synchronization primitive for that is not a file_lock (the OS already locks the file), it is a named mutex. Use, say, boost's named_mutex class.

Do keep in mind that this is a very low-level interop mechanism and comes without any conveniences whatsoever. By the time you add all of the required synchronization, you're half-way to what the OS already does with a named pipe or local-loopback socket. If you discover that you have to copy data into the mapped view, not uncommon since it is not easily resizable, then you've lost all benefits.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thanks Hans - I guess what I'm really asking then is - is it safe to use the file i'm memory mapping as the argument for the file_lock constructor? – Dave F Feb 09 '15 at 14:53
  • No need to lock the file, the operating system already does this. If you need to arbitrate access to the mmf, almost always required, then use a named_mutex instead. – Hans Passant Feb 09 '15 at 15:02
  • OK - I was worried in case a process hung onto the mutex and crashed – Dave F Feb 09 '15 at 16:44
  • @DaveF I'd look into that some more. I remember there being some pretty annoying edge cases, of course fixable, but not nearly as trivial as one would like (see e.g. [this answer to *"How to limit the number of running instances in C++"*](http://stackoverflow.com/a/22545891/85371)). That's with a names Semaphore, but it shows the same dilemma. – sehe Feb 09 '15 at 21:44
  • 1
    @sehe Yes, it's a tricky one; I've deliberately stopped the process within find_or_construct while it had the mutex locked, then run the process again - it hangs locking the mutex in find_or_construct. So it's not straightforward, certainly. – Dave F Feb 10 '15 at 10:23
  • Boost **does** do something to the file, and that's truncating it. Rather annoying undocumented behavior. – MSalters Feb 02 '16 at 08:04
  • > you almost always need to arbitrate access to the memory mapped file ... The most suitable synchronization primitive for that is not a `file_lock` ... @HansPassant why do you say this? `file_lock` is an inter-process synchronization mechanism for file access. – pooya13 Apr 01 '21 at 04:14