A Mutex is like a C# lock, but it can work
across multiple processes. In other words, Mutex can be computer-wide as well as
application-wide.
A Mutex is a synchronization primitive that can
also be used for interprocess synchronization. When two or more threads need to
access a shared resource at the same time, the system needs a synchronization
mechanism to ensure that only one thread at a time uses the resource. Mutex is a
synchronization primitive that grants exclusive access to the shared resource to
only one thread. If a thread acquires a Mutex, the second thread that wants to
acquire that Mutex is suspended until the first thread releases the Mutex.
In short, A mutual exclusion ("Mutex") is a mechanism that acts as a flag to prevent two threads from performing one or more actions simultaneously. The entire action that you want to run exclusively is called a critical section or protected section.
A critical
section is
a piece of code that accesses a
shared resource (data structure or device)
but the condition is that only one thread can enter in this section at a time.
Modern programming languages support this natively. In C#, it's
as simple as:
-
Instantiating a new static Mutex object that's accessible
from each thread.
-
Wrapping whatever code you want to be executed in the
critical section with that object's WaitOne() and ReleaseMutex() methods in
each thread
With a Mutex class, you call the
WaitHandle.WaitOne method to lock and ReleaseMutex to unlock. Closing or
disposing a Mutex automatically releases it. Just as with the lock statement, a
Mutex can be released only from the same thread that obtained it.
This example shows how a local Mutex object
is used to synchronize access to a protected resource.
using
System;
using
System.Collections;
using
System.Threading;
namespace
Mutexclass
{
class Akshay
{
private
static Mutex mutex =
new Mutex();
private const
int numhits = 1;
private const
int numThreads = 4;
private
static void ThreadProcess()
{
for (int
i = 0; i < numhits; i++)
{
UseCsharpcorner();
}
}
private
static void UseCsharpcorner()
{
mutex.WaitOne(); // Wait until it is
safe to enter.
Console.WriteLine("{0}
has entered in the C_sharpcorner.com",
Thread.CurrentThread.Name);
// Place code to access non-reentrant
resources here.
Thread.Sleep(500);
// Wait until it is safe to enter.
Console.WriteLine("{0}
is leaving the C_sharpcorner.com\r\n",
Thread.CurrentThread.Name);
mutex.ReleaseMutex(); // Release the
Mutex.
}
static
void Main(string[] args)
{
for (int
i = 0; i < numThreads; i++)
{
Thread mycorner =
new Thread(new
ThreadStart(ThreadProcess));
mycorner.Name = String.Format("Thread{0}",
i + 1);
mycorner.Start();
}
Console.Read();
}
}
}
Output
Use a Mutex to control a shared resource
against two current threads
using
System;
using
System.Threading;
class
MyCounter
{
public static
int count = 0;
public static
Mutex MuTexLock =
new Mutex();
}
class
IncThread
{
public Thread
th;
public IncThread()
{
th = new
Thread(this.GO);
th.Start();
}
void Go()
{
Console.WriteLine("IncThread
is waiting for the mutex.");
MyCounter.MuTexLock.WaitOne();
Console.WriteLine("IncThread
acquires the mutex.");
int num = 10;
do
{
Thread.Sleep(50);
MyCounter.count++;
Console.WriteLine("In
IncThread, MyCounter.count is " + MyCounter.count);
num--;
} while (num > 0);
Console.WriteLine("IncThread
releases the mutex.");
MyCounter.MuTexLock.ReleaseMutex();
}
}
class
DecThread
{
public Thread
th;
public DecThread()
{
th = new
Thread(new
ThreadStart(this.Go));
th.Start();
}|
void Go()
| {
Console.WriteLine("DecThread
is waiting for the mutex.");
MyCounter.MuTexLock.WaitOne();
Console.WriteLine("DecThread
acquires the mutex.");
int num = 10;
do
{
Thread.Sleep(50);
MyCounter.count--;
Console.WriteLine("In
DecThread, MyCounter.count is " + MyCounter.count);
num--;
} while (num > 0);
Console.WriteLine("DecThread
releases the mutex.");
MyCounter.MuTexLock.ReleaseMutex();
}
}
class
MainClass
{
public static
void Main()
{|
IncThread myt1 =
new IncThread();
DecThread myt2 =
new DecThread();
myt1.thrd.Join();
myt2.thrd.Join();
Console.Read();
}
}
Output
Use the Mutex object: WaitOne
An overloaded WaitOne() method also accepts a TimeSpan object, useful if the thread should wait only until a period of time has lapsed. Typically this is employed when there's a risk ofdeadlock, where two or more threads are waiting for the same Mutex to become available simultaneously. Deadlock is as bad as it sounds, since it can result in an application that has "stalled out" for all intents and purposes.
using
System;
using
System.Threading;
namespace
waitonmethod
{
class Akshay
{
private
static int Runs = 0;
static
Mutex mutex = new
Mutex(false,
"RunsMutex");|
public static
void CountUp()
{
while (Runs < 10)
{
// acquire the mutex
mutex.WaitOne();
int Temp = Runs;
Temp++;
Console.WriteLine(Thread.CurrentThread.Name
+ " " + Temp);
Thread.Sleep(800);
Runs = Temp;
// release the mutex
mutex.ReleaseMutex();
}
}
public static
void Main()
{
Thread t2 =
new Thread(new
ThreadStart(CountUp));
t2.Name = "t2";
Thread t3 =
new Thread(new
ThreadStart(CountUp));
t3.Name = "t3";
t2.Start();
t3.Start();
Console.Read();
}
}
}
Output
Own a Mutex
A Mutex object can be owned by a thread. When owned, it can only
be owned by one single thread. When it is owned by a thread, other threads
cannot own it until the original thread owner releases it. A thread which wants
to own a Mutex calls the Mutex instance's WaitOne() method. An owning thread
which wants to release the Mutex calls the ReleaseMutex() method.
using
System;|
using
System.Threading;
namespace
ownamutex
{
class Akshay
{
public static
void Main()
{
bool ownsMutex;
using (Mutex
mutex = new Mutex(true,
"MutexExample",
out ownsMutex))
{
if (ownsMutex)
{
Console.WriteLine("Owned");
mutex.ReleaseMutex();
}
else
{
Console.WriteLine("Another
instance of this application " +" already
owns the mutex named MutexExample.");
}
}
Console.Read();
}
}
}
Output
Name a Mutex
A Mutex can be either named or unnamed. If a Mutex is named, it
is eligible to be a system-wide Mutex that can be accessed from multiple
processes. If a Mutex is unnamed, it is an anonymous Mutex which can only be
accessed within the process in which it is created.
using
System;
using
System.Threading;
namespace
Namingthread
{
class Akshay
{
public static
void Main(string[]
args)
{
string mutexName =
"akshay";
Mutex m =
new Mutex(false,
mutexName);
for (; ; )
{
m.WaitOne();
Console.WriteLine("Have
Mutex");
Console.WriteLine("Releasing");
m.ReleaseMutex();
}
Console.Read();
}
}
}
output