What is the difference between lock and Mutex? Why can't they be used interchangeably?
A lock is specific to the AppDomain, while Mutex to the Operating System allowing you to perform cross-process locking and synchronization.
Mutex is a cross process and there will be a classic example of not running more than one instance of an application.
2nd example is say you are having a file and you don't want different process to access the same file , you can implement a Mutex but remember one thing Mutex is a operating system wide and cannot used between two remote process.
Lock is a simplest way to protect section of your code and it is appdomain specific , you can replace lock with Moniters if you want more controlled synchronization.
lock
is a compiler keyword, not an actual class or object. It's a wrapper around the functionality of the Monitor
class and is designed to make the Monitor
easier to work with for the common case.
The Monitor
(and the lock
keyword) are, as Darin said, restricted to the AppDomain
. Primarily because a reference to a memory address (in the form of an instantiated object) is required to manage the "lock" and maintain the identity of the Monitor
The Mutex
, on the other hand, is a .Net wrapper around an operating system construct, and can be used for system-wide synchronization, using string data (instead of a pointer to data) as its identifier. Two mutexes that reference two strings in two completely different memory addresses, but having the same data, will actually utilize the same operating-system mutex.
I use a Mutex to check see if I already have a copy of the application running on the same machine.
bool firstInstance;
Mutex mutex = new Mutex(false, @"Local\DASHBOARD_MAIN_APPLICATION", out firstInstance);
if (!firstInstance)
{
//another copy of this application running
}
else
{
//run main application loop here.
}
// Refer to the mutex down here so garbage collection doesn't chuck it out.
GC.KeepAlive(mutex);
A Mutex
can be either local to a process or system-wide. MSDN:
Mutexes are of two types: local mutexes, which are unnamed, and named system mutexes. A local mutex exists only within your process.
Furthermore, one should take special care - detailed on the same page as well - when using a system-wide mutex on a system with Terminal Services.
One of the differences between Mutex
and lock
is that Mutex
utilizes a kernel-level construct, so synchronization will always require at least a user space-kernel space transition.
lock
- that is really a shortcut to the Monitor
class, on the other hand tries to avoid allocating kernel resources and transitioning to kernel code (and is thus leaner & faster - if one has to find a WinAPI construct that it resembles, it would be CriticalSection
).
The other difference is what others point out: a named Mutex
can be used across processes.
Unless one has special needs or requires synchronization across processes, it is just better to stick to lock
(aka Monitor
)˛
There are several other "minor" differences, like how abandonment is handled, etc.
The same can be said about ReaderWriterLock
and ReaderWriterLockSlim
in 3.5, Semaphore
and the new SemaphoreSlim
in .NET 4.0 etc.
It is true that the latter xxSlim
classes cannot be used as a system-wide sync primitives, but they were never meant to - they were "only" meant to be faster and more resource friendly.