3

Does Windows offer any kind of mutex that can be placed in a memory mapped file and used across multiple processes?

Ideally it must be completely self contained such that it can survive by itself in the file, even across a reboot. Also, no resources should be leaked if I simply remove the file manually while no processes are running.

If possible the solution should also offer the accompanying 'condition' concept which should also be an object that can sit in a shared memory mapped file.

In short, I need something similar to a PTHREADS mutex with the SHARED attribute.

As far as I understand, simply using a PTHREADS mutex is not possible because the SHARED attribute is unsupported in the Windows port of PTHREADS.

Kristian Spangsege
  • 2,903
  • 1
  • 20
  • 43
  • Also, if the solution offers the same level of robustness as a PTHREADS mutex with both the SHARE and the ROBUST attributes, it would be a huge plus. I.e. robust detection of the case where a process dies while it is inside a critical region. – Kristian Spangsege Jan 18 '13 at 15:25
  • 2
    AFAIK, there is nothing offered by MS here, though it seems possible (but non-trivial) to roll your own solution. (NB. Look [here](http://stackoverflow.com/questions/13532189/robust-critcal-section-for-shared-memory) for shared-memory mutex in boost which spins and yields on contention). (BTW, for your real problem, is not `CreateMutex` with named mutex enough? It works between processes, it's just too slow due to unconditional syscall) – Anton Kovalenko Jan 18 '13 at 15:46
  • @Anton Highly relevant discussion on that link. Thanks. – Kristian Spangsege Jan 18 '13 at 16:52

3 Answers3

3

To share a synchronization object, give it a name and use the same name in each process when you Create the object.

The following synchronization objects can be shared between process that way :

Critical sections cannot be shared, but are faster.

Testing or waiting on those objects is done with the wait family of functions, often WaitForMultipleObjects.

ixe013
  • 9,559
  • 3
  • 46
  • 77
  • Using a named mutex could probably work for me, however, if I need to accept the penalty of a system call for every locking operation, then I would probably resort to simply use file locking (LockFileEx) since in my case I already have the shared memory mapped file open. – Kristian Spangsege Jan 18 '13 at 16:42
  • It looks like 'Event' is what corresponds most closely to the concept of a condition from monitor terminology. Is that right? – Kristian Spangsege Jan 18 '13 at 16:42
  • @KristianSpangsege In most cases, Event is not a drop-in replacement for condvar -- and trying to replace conditions with events leads to all kinds of subtle bugs. E.g. would you use manual-reset event or auto-reset? If auto-reset, it's hard to broadcast; if manual-reset, who will reset it after broadcast? (the latter problem makes it especially tempting to use `PulseEvent` call, which is **deadly wrong**). It's better to find some condition implementation over WinAPI and plagiarize (there are different variants, but not too trivial). Getting it right for the first time is very hard. – Anton Kovalenko Jan 18 '13 at 17:02
3

Use the file as its own mutex: Use the LockFileEx function and have everybody agree to lock byte 0 of the file when they want to claim the mutex.

Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
1

That's not possible. The mutex object itself lives in kernel space to protect it from user code messing with its state. The handle you acquired to it is only valid for the process that acquired it. Technically you could use DuplicateHandle() and put the returned handle in the mmf, but only if you have a handle to the other process that accesses the memory section. That's fairly brittle.

This is why you can specify a name for the mutex in the CreateMutex() function. The other process gets to it by using the same name in the OpenMutex call.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 1
    1. Fortunately, `CreateMutex` is also able to open existing mutexes, so the process doesn't have to know whether it's the first (creator) or not. 2. The interesting thing is, can't we implement the *fast path* of lock/unlock with atomic ops on shared memory, resorting to a named semaphore on contention -- like a critical section does, internally. And I fail to see why it's impossible. – Anton Kovalenko Jan 18 '13 at 15:56
  • @Antom Interesting idea. Where do I see which atomic ops are offered on Windows? – Kristian Spangsege Jan 18 '13 at 16:24
  • 1
    @KristianSpangsege it's the `Interlocked*` function family. Start from here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684122(v=vs.85).aspx – Anton Kovalenko Jan 18 '13 at 16:28