views:

4640

answers:

6

Can someone explain the difference between:

  • lock (someobject) {}
  • Using Mutex
  • Using Semaphore
  • Using Monitor
  • Using Other .Net synchronization classes

I just can't figure it out. It seems to me the first two are the same?

+17  A: 

Great question. I maybe wrong.. Let me try.. Revision#2 of my orig answer.. with a little bit of more understanding. Thanks for making me read :)

lock(obj)

  • is a CLR construct that for (intra-object?) thread synchronization. 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. Also it is recommended that you lock on a private member object of your class.

Monitors

  • 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.

Using a lock or monitor is useful for preventing the simultaneous execution of thread-sensitive blocks of code, but these constructs do not allow one thread to communicate an event to another. This requires synchronization events, which are objects that have one of two states, signaled and un-signaled, that can be used to activate and suspend threads. Mutex, Semaphores are OS-level concepts. e.g with a named mutex you could synchronize across multiple (managed) exes (ensuring that only one instance of your application is running on the machine.)

Mutex:

  • Unlike monitors, however, 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.

Semaphores (hurt my brain).

  • Use the Semaphore class to control access to a pool of resources. Threads enter the semaphore by calling the WaitOne method, which is inherited from the WaitHandle class, and release the semaphore by calling the Release method. The count on a semaphore is decremented each time a thread enters the semaphore, and incremented when a thread releases the semaphore. When the count is zero, subsequent requests block until other threads release the semaphore. When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created. A thread can enter the semaphore multiple times..The Semaphore class does not enforce thread identity on WaitOne or Release.. programmers responsibility to not muck up. Semaphores are of two types: local semaphores and named system semaphores. If you create a Semaphore object using a constructor that accepts a name, it is associated with an operating-system semaphore of that name. Named system semaphores are visible throughout the operating system, and can be used to synchronize the activities of processes. A local semaphore exists only within your process. It can be used by any thread in your process that has a reference to the local Semaphore object. Each Semaphore object is a separate local semaphore.

THE PAGE TO READ - Thread Synchronization (C#)

Gishu
You claim that `Monitor` doesn't allow communication is incorrect; you can still `Pulse` etc with a `Monitor`
Marc Gravell
+6  A: 

As stated in ECMA, and as you can observe from Reflected methods the lock statement is basically equivalent to

object obj = x;
System.Threading.Monitor.Enter(obj);
try {
   …
}
finally {
   System.Threading.Monitor.Exit(obj);
}

From the aforementioned example we see that Monitors can lock on objects.

Mutexe's are useful when you need interprocess synchronization as they can lock on a string identifier. The same string identifier can be used by different processes to acquire the lock.

Semaphores are like Mutexes on steroids, they allow concurrent access by providing a maximum count of concurrent access'. Once the limit is reached the semaphore starts blocking any further access to the resource until one of the callers releases the semaphore.

arul
Yeah... Syntactic sugar baby! Sweeeet
Peter Gfader
This syntactic sugar has been slightly changed in C#4Check out http://blogs.msdn.com/ericlippert/archive/2009/03/06/locks-and-exceptions-do-not-mix.aspx
Peter Gfader
+8  A: 

Re "Using Other .Net synchronization classes"- some of the others you should know about:

There are also more (low overhead) locking constructs in CCR/TPL (the Parallel Extensions CTP) - but IIRC, these will be made available in .NET 4.0

Marc Gravell
A: 

Hi

right now we are developing a our own database Like MySQL in C# using LINQ so provide information in which locking system we are include it's argent's......

+5  A: 

An additional caveat for locking on any shared Mutex you've identified with a string ID is that it will default to a "Local\" mutex and will not be shared across sessions in a terminal server environment.

Prefix your string identifier with "Global\" to ensure that access to shared system resources is properly controlled. I was just running into a whole heap of problems synchronizing communications with a service running under the SYSTEM account before I realized this.

nvuono
+1  A: 

I would try to avoid lock() and Mutex, Monitor if you can...

Check out the new namespace System.Collections.Concurrent in .NET 4
It has some nice thread-safe collection classes

http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx

ConcurrentDictionary rocks! no manual locking anymore for me!

Peter Gfader