You can use the System.Threading.Mutex class, which has an OpenExisting method to open a named system mutex.
That doesn't answer the question:
How can I create a system/multiprocess Mutex
To create a system-wide mutex, call the System.Threading.Mutex constructor that takes a string as an argument. This is also known as a 'named' mutex. To see if it exists, I can't seem to find a more graceful method than try catch:
System.Threading.Mutex _mutey = null;
try
{
_mutey = System.Threading.Mutex.OpenExisting("mutex_name");
//we got Mutey and can try to obtain a lock by waitone
_mutey.WaitOne();
}
catch
{
//the specified mutex doesn't exist, we should create it
_mutey = new System.Threading.Mutex("mutex_name"); //these names need to match.
}
Now, to be a good programmer, you need to, when you end the program, release this mutex
_mutey.ReleaseMutex();
or, you can leave it in which case it will be called 'abandoned' when your thread exits, and will allow another process to create it.
[EDIT]
As a side note to the last sentence describing the mutex that is abandoned, when another thread acquires the mutex, the exception System.Threading.AbandonedMutexException
will be thrown telling him it was found in the abandoned state.
[EDIT TWO]
I'm not sure why I answered the question that way years ago; there is (and was) a constructor overload that is much better at checking for an existing mutex. In fact, the code I gave seems to have a race condition! (And shame on you all for not correcting me! :-P )
Here's the race condition: Imagine two processes, they both try to open the existing mutex at the same time, and both get to the catch section of code. Then, one of the processes creates the mutex and lives happily ever after. The other process, however, tries to create the mutex, but this time it's already created! This checking/creating of a mutex needs to be atomic.
http://msdn.microsoft.com/en-us/library/bwe34f1k(v=vs.90).aspx
So...
var requestInitialOwnership = false;
bool mutexWasCreated;
Mutex m = new Mutex(requestInitialOwnership,
"MyMutex", out mutexWasCreated);
I think the trick here is that it appears that you have an option that you don't actually have (looks like a design flaw to me). You sometimes can't tell if you own the mutex if you send true
for requestInitialOwnership
. If you pass true
and it appears that your call created the mutex, then obviously you own it (confirmed by documentation). If you pass true
and your call did not create the mutex, all you know is that the mutex was already created, you don't know if some other process or thread which perhaps created the mutex currently owns the mutex. So, you have to WaitOne
to make sure you have it. But then, how many Release
s do you do? If some other process owned the mutex when you got it, then only your explicit call to WaitOne
needs to be Release
d. If your call to the constructor caused you to own the mutex, and you called WaitOne
explicitly, you'll need two Release
s.
I'll put these words into code:
var requestInitialOwnership = true; /*This appears to be a mistake.*/
bool mutexWasCreated;
Mutex m = new Mutex(requestInitialOwnership,
"MyMutex", out mutexWasCreated);
if ( !mutexWasCreated )
{
bool calledWaitOne = false;
if ( ! iOwnMutex(m) ) /*I don't know of a method like this*/
{
calledWaitOne = true;
m.WaitOne();
}
doWorkWhileHoldingMutex();
m.Release();
if ( calledWaitOne )
{
m.Release();
}
}
Since I don't see a way to test whether you currently own the mutex, I will strongly recommend that you pass false
to the constructor so that you know that you don't own the mutex, and you know how many times to call Release
.