Reputation: 31848
How can I create a system/multiprocess Mutex to co-ordinate multiple processes using the same unmanaged resource.
Background: I've written a procedure that uses a File printer, which can only be used by one process at a time. If I wanted to use it on multiple programs running on the computer, I'd need a way to synchronize this across the system.
Upvotes: 16
Views: 23678
Reputation: 7768
There is a constructor overload for checking for an existing mutex.
http://msdn.microsoft.com/en-us/library/bwe34f1k(v=vs.90).aspx
So...
void doWorkWhileHoldingMutex()
{
Console.WriteLine(" Sleeping...");
System.Threading.Thread.Sleep(1000);
}
var requestInitialOwnership = true;
bool mutexWasCreated;
Mutex m = new Mutex(requestInitialOwnership,
"MyMutex", out mutexWasCreated);
if (requestInitialOwnership && mutexWasCreated)
{
Console.WriteLine("We own the mutex");
}
else
{
Console.WriteLine("Mutex was created, but is not owned. Waiting on it...");
m.WaitOne();
Console.WriteLine("Now own the mutex.");
}
doWorkWhileHoldingMutex();
Console.WriteLine("Finished working. Releasing mutex.");
m.ReleaseMutex();
If you fail to call m.ReleaseMutex()
it will be called 'abandoned' when your thread exits. When another thread constructs the mutex, the exception System.Threading.AbandonedMutexException
will be thrown telling him it was found in the abandoned state.
Upvotes: 33
Reputation: 2290
I have not had good luck using the System Mutex described above using Mono under Linux. I'm probably just doing something simple wrong but the following works well and cleans up nicely if the process exits unexpectedly (kill -9 ). Would would be interested to hear comments or critisisms.
class SocketMutex{
private Socket _sock;
private IPEndPoint _ep;
public SocketMutex(){
_ep = new IPEndPoint(IPAddress.Parse( "127.0.0.1" ), 7177);
_sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_sock.ExclusiveAddressUse = true; // most critical if you want this to be a system wide mutex
}
public bool GetLock(){
try{
_sock.Bind(_ep); // 'SocketException: Address already in use'
}catch(SocketException se){
Console.Error.WriteLine ("SocketMutex Exception: " se.Message);
return false;
}
return true;
}
}
Upvotes: 0
Reputation: 99859
You can use the System.Threading.Mutex
class, which has an OpenExisting
method to open a named system mutex.
Upvotes: 4