What is the difference between lock and Mutex? - c#

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 inter-process locking and synchronization (IPC).

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.

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.

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 lot has been said already, but to make it simple, here's my take.
lock -> Simple to use, wrapper on monitor, locks across threads in an AppDomain.
unnamed mutex -> similar to lock except locking scope is more and it's across AppDomain in a process.
Named mutex -> locking scope is even more than unnamed mutex and it's across process in an operating system.
So now options are there, you need to choose the one fits best in your case.

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.

Few more minor differences which were not mentioned in the answers:
In the case of using locks, you can be sure that the lock will be released when an exception happens inside the lock's block.
That's because the lock uses monitors under the hood and is implemented this way:
object __lockObj = x;
bool __lockWasTaken = false;
try
{
System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken);
// Your code...
}
finally
{
if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);
}
Thus, in any case, the lock is released, and you don't need to release it manually (like you'd do for the mutexes).
For Locks, you usually use a private object to lock (and should use).
This is done for many reasons. (More info: see this answer and official documentation).
So, in case of locks, you can't (accidentally gain) access to the locked object from the outside and cause some damage.
But in case of Mutex, you can, as it's common to have a Mutex which is marked public and used from anywhere.

The Lock and Monitors are basically used to provide thread safety for threads that are generated by the application itself i.e. Internal Threads. On the other hand, Mutex ensures thread safety for threads that are generated by the external applications i.e. External Threads. Using Mutex, only one external thread can access our application code at any given point in time.
read this

Related

C# NamedPipe thread safety on async calls

I wonder how to guarantee thread-safety on pipes during async operations.
For example this code is being executed by a thread (the stream has been created properly before):
pipeClientStream.ConnectAsync(cancel).Wait();
Meanwhile another thread wants to know if the pipe is (already) connected
bool isConnected = pipeClientStream.IsConnected;
I didn't find a notice about thread-safety in the microsoft docs, but I guess if it was thread-safe there would be a hint. I also dived into reference source of the Pipe.cs and PipeStream.cs to look for locks but there where none to be found.
So in the end the only "safe" way would be to create a "locked" boolean value set by the thread which is working with the pipe and encapsulate the pipe.
What do you think is proper way of dealing with such scenarios?
the proper way to deal with most non-threadsafe object is to lock it:
lock(pipeClientStream){
return pipeClientStream.IsConnected;
}
Locking a shared resource like this is fine, but it it also common to use a separate object to control access to some resource. If you are using actual asynchronous code you might need some other solution.
do not try to create your own "lock" by using any kind of shared boolean. There is a huge risk you will get something wrong and end up with non threadsafe code.
There are also named mutexes if you need synchronization between processes, but that is not needed if you keep to a single process.

Locking mechanism is needed for static functions?

I have created a CommonUtils.cs file containing 5 static functions (So that I can just "copy" this .cs for other projects in Visual Studio since I develop different C# applications) along with that I have many source files.
Now, I have compiled my project to a DLL. This dll is hosted via IIS server as an application. Many customers use this dll to perform something, say they generate a report.
I have been informed that "static functions" must not be used generously in this context and they should be applied, a "locking" mechanism since without lock, multiple threads of a single instance of program or multiple instances of a program, both can behave unexpectedly. Is it true?
I have been informed that "static functions" must not be used
generously in this context and they should be applied, a "locking"
mechanism since without lock, multiple threads of a single instance of
program or multiple instances of a program, both can behave
unexpectedly. Is it true?
Let's break it piece by piece. What is a static class?
A static class is basically the same as a non-static class, but
there is one difference: a static class cannot be instantiated. In
other words, you cannot use the new keyword to create a variable of
the class type. Because there is no instance variable, you access
the members of a static class by using the class name itself.
How CLR treats a static class?
As is the case with all class types, the type information for a static
class is loaded by the .NET Framework common language runtime (CLR)
when the program that references the class is loaded. The program
cannot specify exactly when the class is loaded. However, it is
guaranteed to be loaded and to have its fields initialized and its
static constructor called before the class is referenced for the first
time in your program. A static constructor is only called one time,
and a static class remains in memory for the lifetime of the
application domain in which your program resides.
Now why we may need locking?
Basically, locking is needed when we have race conditions. When someone may read data that someone else may alter them in the same time. Two separate threads have access to a shared resource and there isn't any mechanism to prevent this. In order you take an answer to your question, you have at first to answer another question.
Does your static methods access shared resources and there might be any race condition? If that's true, then you need to use locking. Otherwise, it is not needed.
For further information about static classes, please have a look here.
While if you need more information about thread synchronization techniques, please have a look here.
Functions are immutable so you don't need to synchronize when calling a function. Function parameters are mutable but each invocation has it's own local copy. No need to synchronize either.
Synchronization is required when multiple thread work on the same data and there is at least one writer. This is about any variable that is shared between threads. Care is required for static variables and any instance variable reachable by a static variables.
It sounds like you have a class library. Here are Microsoft's guidelines for class libraries that need to support multi threading:
Avoid the need for synchronization, if possible. This is especially true for heavily used code. For example, an algorithm might be adjusted to tolerate a race condition rather than eliminate it. Unnecessary synchronization decreases performance and creates the possibility of deadlocks and race conditions.
Make static data (Shared in Visual Basic) thread safe by default.
Do not make instance data thread safe by default. Adding locks to create thread-safe code decreases performance, increases lock contention, and creates the possibility for deadlocks to occur. In common application models, only one thread at a time executes user code, which minimizes the need for thread safety. For this reason, the .NET Framework class libraries are not thread safe by default.
Avoid providing static methods that alter static state. In common server scenarios, static state is shared across requests, which means multiple threads can execute that code at the same time. This opens up the possibility of threading bugs. Consider using a design pattern that encapsulates data into instances that are not shared across requests. Furthermore, if static data are synchronized, calls between static methods that alter state can result in deadlocks or redundant synchronization, adversely affecting performance.
Copied from https://msdn.microsoft.com/en-us/library/1c9txz50(v=vs.110).aspx
Explanation for "LOCK" From MSDN says:
The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock.
The lock keyword ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread tries to enter a locked code, it will wait, block, until the object is released
References:
https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
Its better to use LOCK in Multithreading than creating Static functions everytime.

Does Mutex in C# busy wait?

I am wondering if the Mutex object busy waits or does it context switch out (i.e. does the thread owning the mutex go to sleep and get woken up later by an interrupt), or is it architecture dependent (i.e. number of cores your machine has)? I am hoping that it actually does a context switch out. Thank you in advance.
As per the documentation, Mutex.WaitOne "Blocks the current thread until the current WaitHandle receives a signal", which means it's put to sleep.
Internally, WaitHandle.WaitOne will call WaitForSingleObjectEx from the Windows API, which:
Waits until the specified object is in the signaled state, an I/O completion routine or asynchronous procedure call (APC) is queued to the thread, or the time-out interval elapses.
Also, according to another document on Context Switches
When a running thread needs to wait, it relinquishes the remainder of its time slice.
A good answer to draw from is here: When should one use a spinlock instead of a mutex?
The answer is that it depends. The Mutex class in .Net is typically backed by the operating system, since it is a lock that can be shared between multiple processes; it is not intended to be used only within a single process.
This means that we're at the mercy of our operating system's implementation. Most modern OSes, including Windows, implement adaptive mutexes for multi-core machines.
Drawing from the above answer, we learn that implementing locking by suspending the thread is often very expensive, since it requires at least 2 context switches. On a multi-core system, we can avoid some context switches by attempting to spin-wait initially to acquire the lock - if the lock is lightly contended, you'll likely acquire the lock in the spinwait, and thus never suffer the penalty of a context switch/thread suspension. In the case that the timeout expires while the spinwait is occurring, the lock will downgrade to full thread suspension to keep from wasting too much cpu.
None of this makes sense on a single-core machine, since you'd just be burning CPU while the holder of the lock is waiting to run to finish the work it needs to do in order to release the lock. Adaptive locks are not used on single-core machines.
So, to directly answer your question - it is likely that the Mutex class does both - it'll busy-wait (spin-wait) for a short while to see if it can acquire the mutex without performing a context switch, and if it can't do so in the short amount of time it allows itself, it'll suspend the thread. It's important to note that the amount of time it'll spinwait for is usually very short, and that overall, this strategy can significantly reduce total CPU usage or increase overall lock throughput. So, even though we're burning CPU spin-waiting, we'll probably save more CPU overall.
In context of .Net, the Mutex class provides mutual exclusion, but is meant to be used between multiple processes, and thus tends to be quite slow. Specifically, the implementation of the Mutex class in the Microsoft .Net Framework, the .Net Mutex class uses the Win32 Mutex object.
Do note that the details may change depending on which implementation of .Net you're using, and on which operating system. I've tried to provide a .Net/Microsoft/Windows-centric treatment of the topic since that is the most common circumstance.
As an aside, if you only need locking within a single process, the Monitor class, or its keyword lock, should be used instead. A similar dichotomy exists for semaphores - the Semaphore class is, in the end, implemented by the operating system - it can be used for inter-process communication and thus tends to be slow; the SemaphoreSlim class is implemented natively in .Net, can be used only within a single process, and tends to be faster. On this point, a good msdn article to read is Overview of Synchronization Primitives.

Multi-threading concept and lock in c#

I read about lock, though not understood nothing at all.
My question is why do we use a un-used object and lock that and how this makes something thread-safe or how this helps in multi-threading ? Isn't there other way to make thread-safe code.
public class test {
private object Lock { get; set; }
...
lock (this.Lock) { ... }
...
}
Sorry is my question is very stupid, but i don't understand, although i've used it many times.
Accessing a piece of data from one thread while other thread is modifying it is called "data race condition" (or just "data race") and can lead to corruption of data. (*)
Locks are simply a mechanism for avoiding data races. If two (or more) concurrent threads lock the same lock object, then they are no longer concurrent and can no longer cause data races, for the duration of the lock. Essentially, we are serializing the access to shared data.
The trick is to keep your locks as "wide" as you must to avoid data races, yet as "narrow" as you can to gain performance through concurrent execution. This is a fine balance that can easily go out of whack in either direction, which is why multi-threaded programming is hard.
Some guidelines:
As long all threads are just reading the data and none will ever modify it, lock is unnecessary.
Conversely, if at least one thread might at some point modify the data, then all concurrent code paths accessing that same data must be properly serialized through locks, even those that only read the data.
Using a lock in one code path but not the other will leave the data wide open to race conditions.
Also, using one lock object in one code path, but a different lock object in another (concurrent) code path does not serialize these code paths and leaves you wide open to data races.
On the other hand, if two concurrent code paths access different data, they can use different lock objects. But, whenever there is more than one lock object, watch out for deadlocks. A deadlock is often also a "code race condition" (and a heisenbug, see below).
The lock object does not need to be (and usually isn't) the same thing as the data you are trying to protect. Unfortunately, there is no language facility that lets you "declare" which data is protected by which lock object, so you'll have to very carefully document your "locking convention" both for other people that might maintain your code, and for yourself (since even after a short time you will forget some of the nooks and crannies of your locking convention).
It's usually a good idea to protect the lock object from the outside world as much as you can. After all, you are using it for the very sensitive task of locking and you don't want it locked by external actors in unforeseen ways. That's why using this or a public field as a lock object is usually a bad idea.
The lock keyword is simply a more convenient syntax for Monitor.Enter and Monitor.Exit.
The lock object can be any object in .NET, but value objects will be boxed in the call to Monitor.Enter, which means threads will not share the same lock object, leaving the data unprotected. Therefore, only use reference types as lock objects.
For inter-process communication you can use a global mutex, which can be created by passing a non-empty name to Mutex Constructor. Global mutexes provide essentially the same functionality as regular "local" locking, except they can be shared between separate processes.
There are synchronization mechanisms other than locks, such as semaphores, condition variables, message queues or atomic operations. Be careful when mixing different synchronization mechanisms.
Locks also behave as memory barriers, which is increasingly important on modern multi-core, multi-cache CPUs. This is part of the reason why you need locks on reading the data and not just writing.
(*) It is called "race" because concurrent threads are "racing" towards performing an operation on the shared data and whoever wins that race determines the outcome of the operation. So the outcome depends on timing of the execution, which is essentially random on modern preemptive multitasking OSes. Worse yet, timing is easily modified by a simple act of observing the program execution through tools such as debugger, which makes them "heisenbugs" (i.e. the phenomenon being observed is changed by the mere act of observation).
Lock object is like a door into the single room where only one guest per time can enter.
The room can be your data, the guest can be your function.
define data (room)
add door (lock object)
invite guests (functions)
using lock insctruction close/open door to allow only one guest per time enter into the room.
Why we need this? If you simulatniously write a data in a file (just an example, can be 1000s others) you will need to sync an access of your funcitons (close/open door for guests) to the write file, so any function will append to the end of the file (assuming that is requierement of this example)
This is naturally not only way sync the threads, there are more out there:
Monitors
Wait hadlers
...
Check out the link for complete information and description of each of them
Thread Synchronization
Yes, there is indeed another way:
using System.Runtime.CompilerServices;
class Test
{
private object Lock { get; set; }
[MethodImpl(MethodImplOptions.Synchronized)]
public void Foo()
{
// Now this instance is locked
}
}
While it looks more "natural", it's not used often, because of the fact that the object is locking on itself this way, so other code could not risk locking on this object -- it could cause a deadlock.
Because of this, you usually create a (lazy-initialized) private field referring to an object, and use that object as a lock instead. This will guarantee that no one else can lock against the same object as you.
A little more detail on what's happening beneath the hood:
When you "lock on an object", you're not locking on the object itself. Rather, you're using the object as a guaranteed-to-be-unique-address-in-memory throughout your program. When you "lock", the runtime takes the object's address, uses it to look up the actual lock inside another table (which is hidden from you), and uses that object as the ""lock" (also known as a "critical section").
So really, for you, an object is just a proxy/symbol -- it isn't doing anything by itself; it's just acting as a unique indicator that will never clash with another valid object in the same program.
When you have different threads accessing same variable/resource at the same time they may over write on this variable/resource and you can have unexpected results. Lock will make sure only one thread can assess variable at on time and remain thread will queue to get access to this variable/resource till lock is released
suppose we have balance variable of an account.
Two different thread read its value which was 100
Suppose first thread adds 50 to it like 100 + 50 and saves it and balance will have 150
As second thread already read 100 and mean while. suppose it subtract 50 like 100-50 but point to note here is that first thread has made the balance 150 so second thread should to 150-50 this could cause serious problems.
So lock makes sure that when on thread wants to change some resource states it locks it and leaves after committing change
The lock statement introduces the concept of mutual exclusion. Only one thread can acquire a lock on a given object at any one time. This prevents threads from accessing shared data structures concurrently, thus corrupting them.
If other threads already hold a lock, the lock statement will block until it is able to acquire an exclusive lock on its argument before allowing its block to execute.
Note that the only thing lock does is control entry to the block of code. Access to members of the class is completely unrelated to the lock. It is up to the class itself to ensure that accesses that must be synchronized are coordinated by the use of lock or other synchronization primitives. Also note that access to some or all members may not have to be synchronized. For instance, if you want to maintain a counter, you could use the Interlocked class without locking.
An alternative to locking is lock-free data structures, which behave correctly in the presence of multiple threads. Operations on lock-free data structures must be designed very carefully, usually with the assistance of lock-free primitives such as compare-and-swap (CAS).
The general theme of such techniques is to try to perform operations on data structures atomically and detect when operations fail due to concurrent actions by other threads, followed by retries. This works well on a lightly loaded system where failures are unlikely, but can produce runaway behaviour as the failure rate climbs and retries become a dominant load. This problem can be ameliorated by backing off the retry rate, effectively throttling the load.
A more sophisticated alternative is software transactional memory. Unlike CAS, STM generalizes the concept of fail-and-retry to arbitrarily complex memory operations. In simple terms, you start a transaction, perform all your operations, and finally commit. The system detects if the operations cannot succeed due to conflicting operations performed by other threads that beat the current thread to the punch. In such cases, STM can either fail outright, requiring the application to take corrective action, or, in more sophisticated implementations, it can automatically go back to the start of the transaction and try again.
Your confusion is pretty typical for those just getting familiar with the lock keyword in C#. You are right, the object used in the lock statement is really nothing more than a token that defines a critical section. That object, in no way, has any protection from multithreaded access itself.
The way this works is that the CLR reserves a 4 byte (32-bit systems) section in the object header (type handle) called the sync block. The sync block is nothing more than an index into an array that stores the actual critical section information. When you use the lock keyword the CLR will modify this sync block value accordingly.
There are advantages and disadvantages to this scheme. The advantage is that it made for a fairly elegant solution to defining critical sections. One obvious disadvantage is that each object instance contains the sync block and most instances never use it so it would seem to be a waste of space in most cases. Another disadvantage is that boxed value types can be used which is almost always wrong and certainly leads to confusion.
I remember way back when .NET was first released that there was a lot of chatter over whether the lock keyword was good or bad for the language. The general consensus (at least as I remember it) was that it was bad because the using keyword could have been easily used instead. In fact, a solution that used the using keyword actually would have made more sense because it could have been done without the need for the sync block. The c# design team even went on record to say that had they been given a second chance the lock keyword never would have made it into the language.1
1The only reference I could find for this is on Jon Skeet's website here.

Am I really locking this stuff

The environment:
3 web services 2 in the same pool 1 in a different application pool.
They all have the same code trying to access something that is not thread safe say a file that they write to.
I try and lock this code the same way for each web service. I'm not sure if the lock keyword is doing what I want.
One lock I try is this in each web service:
string stringValue
lock (stringValue)
The other lock I try is:
lock (typeof(MyWebServiceClass))
Will these locks prevent any simultaneous writes to the file while it is in use? In this case there are multiple clients hitting each of these web services.
You need a named Mutex to lock on across application pools /processes:
The C# lock keyword is syntactic sugar for Monitor.Enter(), Monitor.Exit() method calls in a try/finally block. Monitor is a light weight (fully managed) synchronization primitive for in-process locking.
A Mutex on the other hand can be either local or global (across processes on the same machine) - global mutexes, also called named mutexes, are visible throughout the operating system, and can be used to synchronize threads in multiple application domains or processes. Also see MSDN.
I think you need to use a Mutex to lock between AppDomains.
Also, for what its worth, avoid locking on a type. That can often result in deadlocks if code elsewhere tries to lock after the first lock has been obtained. It's best to lock on an object whose only purpose is to act as a lock.
For example:
object padlock;
lock(padlock)
{
// work here
}

Categories