Archive

Archive for November, 2012

lock vs Monitor vs Mutex vs Semaphore

November 9, 2012 2 comments

lock

is a CLR construct that for thread synchronization. lock ensures that only one thread can take ownership of the object’s lock & enter the locked block of code. Other threads must wait till the current owner relinquishes the lock by exiting the block of code.

It is recommended that you lock on a private member object of your class.

private static readonly object _SyncLock = new object();
private int _CounterA;
public void IncrementCounterA()
{
lock (_SyncLock)
{
_CounterA++;
}
}

Moniter
lock(obj) is implemented internally using a Monitor. You should prefer lock(obj) because it prevents you from goofing up like forgetting the cleanup procedure. It ‘idiot-proof’s the Monitor construct if you will. Using Monitor is generally preferred over mutexes, because monitors were designed specifically for the .NET Framework and therefore make better use of resources. Monitor is limited to Current Application Domain.

private static readonly object _SyncLock = new object();
private int _CounterB;
public void IncrementCounterB()
{
try
{
Monitor.Enter(_SyncLock);
_CounterB++;
}
finally
{
Monitor.Exit(_SyncLock);
}
}

Mutex
a mutex can be used to synchronize threads across processes. When used for inter-process synchronization, a mutex is called a named mutex because it is to be used in another application, and therefore it cannot be shared by means of a global or static variable. It must be given a name so that both applications can access the same mutex object. In contrast, the Mutex class is a wrapper to a Win32 construct. While it is more powerful than a monitor, a mutex requires interop transitions that are more computationally expensive than those required by the Monitor class.

private Mutex _Mutex = new Mutex(false, “DarksideErrorLog”);
public void LogErrorToFile (string error)
{
try
{
_Mutex.WaitOne();
File.AppendAllText(“errors.log”, error);
}
finally
{
_Mutex.ReleaseMutex();
}
}

Semaphore
Let’s say you have a method that is really CPU intensive, and also makes use of resources that you need to control access to (using Mutexes :)). You’ve also determined that a maximum of five calls to the method is about all your machine can hanlde without making it unresponsive. Your best solution here is to make use of the Semaphore class which allows you to limit a certain number of threads’ access to a resource

private Semaphore _Semaphore = new Semaphore(0, 5, “DarksideIntensiveStuff”);
public void DoIntensiveStuff()
{
try
{
_Semaphore.WaitOne();
//Simulate long-running/cpu-intensive process…
Thread.Sleep(5000);
}
finally
{
_Semaphore.Release(1);
}
}

Categories: C#