Mutex
You can use a Mutex object to synchronize between threads and across processes. Although Mutex doesn't have all the wait and pulse functionality of the Monitor class, it does offer the creation of named mutexes that can be used between processes.
You call WaitOne, WaitAll, or WaitAny to request ownership of the Mutex. The state of the Mutex is signaled if no thread owns it.
If a thread owns a Mutex, that thread can specify the same Mutex in repeated wait-request calls without blocking its execution; however, it must release the Mutex as many times to release ownership.
If a thread terminates normally while owning a Mutex, the state of the Mutex is set to signaled and the next waiting thread gets ownership. The Mutex class corresponds to a Win32 CreateMutex call.
The following C# code example demonstrates the use of Mutex.
using System;
using System.Threading;
public class MutexSample{
static Mutex gM1;
static Mutex gM2;
const int ITERS = 100;
static AutoResetEvent Event1 = new AutoResetEvent(false);
static AutoResetEvent Event2 = new AutoResetEvent(false);
static AutoResetEvent Event3 = new AutoResetEvent(false);
static AutoResetEvent Event4 = new AutoResetEvent(false);
public static void Main(String[] args){
Console.WriteLine("MutexSample.cs ...");
gM1 = new Mutex(true,"MyMutex");
// Create Mutext initialOwned, with name of "MyMutex".
gM2 = new Mutex(true);
// Create Mutext initialOwned, with no name.
Console.WriteLine(" - Main Owns gM1 and gM2");
AutoResetEvent[] evs = new AutoResetEvent[4];
evs[0] = Event1;
// Event for t1.
evs[1] = Event2;
// Event for t2.
evs[2] = Event3;
// Event for t3.
evs[3] = Event4;
// Event for t4.
MutexSample tm = new MutexSample( );
Thread t1 = new Thread(new ThreadStart(tm.t1Start));
Thread t2 = new Thread(new ThreadStart(tm.t2Start));
Thread t3 = new Thread(new ThreadStart(tm.t3Start));
Thread t4 = new Thread(new ThreadStart(tm.t4Start));
t1.Start();
// Calls Mutex.WaitAll(Mutex[] of gM1 and gM2).
t2.Start();
// Calls Mutex.WaitOne(Mutex gM1).
t3.Start();
// Calls Mutex.WaitAny(Mutex[] of gM1 and gM2).
t4.Start();
// Calls Mutex.WaitOne(Mutex gM2).
Thread.Sleep(2000);
Console.WriteLine(" - Main releases gM1");
gM1.ReleaseMutex( );
// t2 and t3 will end and signal.
Thread.Sleep(1000);
Console.WriteLine(" - Main releases gM2");
gM2.ReleaseMutex( );
// t1 and t4 will end and signal.
WaitHandle.WaitAll(evs);
// Waiting until all four threads signal that they are done.
Console.WriteLine("... MutexSample.cs");
}
public void t1Start(){
Console.WriteLine("t1Start started, Mutex.WaitAll(Mutex[])");
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1;
// Create and load an array of Mutex objects for WaitAll call.
gMs[1] = gM2;
Mutex.WaitAll(gMs);
// Waits until both Mutex objects are released.
Thread.Sleep(2000);
Console.WriteLine("t1Start finished, Mutex.WaitAll(Mutex[])");
Event1.Set( );
// AutoResetEvent.Set( ) flagging method is done.
}
public void t2Start(){
Console.WriteLine("t2Start started, gM1.WaitOne( )");
gM1.WaitOne( );
// Waits until Mutex gM1 is released.
Console.WriteLine("t2Start finished, gM1.WaitOne( )");
Event2.Set( );
// AutoResetEvent.Set( ) flagging method is done.
}
public void t3Start(){
Console.WriteLine("t3Start started, Mutex.WaitAny(Mutex[])");
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1;
// Create and load an array of Mutex objects for WaitAny call.
gMs[1] = gM2;
Mutex.WaitAny(gMs);
// Waits until either Mutex object is released.
Console.WriteLine("t3Start finished, Mutex.WaitAny(Mutex[])");
Event3.Set( );
// AutoResetEvent.Set( ) flagging method is done.
}
public void t4Start(){
Console.WriteLine("t4Start started, gM2.WaitOne( )");
gM2.WaitOne( );
// Waits until Mutex gM2 is released.
Console.WriteLine("t4Start finished, gM2.WaitOne( )");
Event4.Set( );
// AutoResetEvent.Set( ) flagging method is done.
}
}
See Also
Threading | Threading Objects and Features | Monitor | Threads and Threading | Mutex Class