[concurrency] Lock, mutex, semaphore... what's the difference?

I will try to cover it with examples:

Lock: One example where you would use lock would be a shared dictionary into which items (that must have unique keys) are added.
The lock would ensure that one thread does not enter the mechanism of code that is checking for item being in dictionary while another thread (that is in the critical section) already has passed this check and is adding the item. If another thread tries to enter a locked code, it will wait (be blocked) until the object is released.

private static readonly Object obj = new Object();

lock (obj) //after object is locked no thread can come in and insert item into dictionary on a different thread right before other thread passed the check...
{
    if (!sharedDict.ContainsKey(key))
    {
        sharedDict.Add(item);
    }
}

Semaphore: Let's say you have a pool of connections, then an single thread might reserve one element in the pool by waiting for the semaphore to get a connection. It then uses the connection and when work is done releases the connection by releasing the semaphore.

Code example that I love is one of bouncer given by @Patric - here it goes:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace TheNightclub
{
    public class Program
    {
        public static Semaphore Bouncer { get; set; }

        public static void Main(string[] args)
        {
            // Create the semaphore with 3 slots, where 3 are available.
            Bouncer = new Semaphore(3, 3);

            // Open the nightclub.
            OpenNightclub();
        }

        public static void OpenNightclub()
        {
            for (int i = 1; i <= 50; i++)
            {
                // Let each guest enter on an own thread.
                Thread thread = new Thread(new ParameterizedThreadStart(Guest));
                thread.Start(i);
            }
        }

        public static void Guest(object args)
        {
            // Wait to enter the nightclub (a semaphore to be released).
            Console.WriteLine("Guest {0} is waiting to entering nightclub.", args);
            Bouncer.WaitOne();          

            // Do some dancing.
            Console.WriteLine("Guest {0} is doing some dancing.", args);
            Thread.Sleep(500);

            // Let one guest out (release one semaphore).
            Console.WriteLine("Guest {0} is leaving the nightclub.", args);
            Bouncer.Release(1);
        }
    }
}

Mutex It is pretty much Semaphore(1,1) and often used globally (application wide otherwise arguably lock is more appropriate). One would use global Mutex when deleting node from a globally accessible list (last thing you want another thread to do something while you are deleting the node). When you acquire Mutex if different thread tries to acquire the same Mutex it will be put to sleep till SAME thread that acquired the Mutex releases it.

Good example on creating global mutex is by @deepee

class SingleGlobalInstance : IDisposable
{
    public bool hasHandle = false;
    Mutex mutex;

    private void InitMutex()
    {
        string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
        string mutexId = string.Format("Global\\{{{0}}}", appGuid);
        mutex = new Mutex(false, mutexId);

        var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
        var securitySettings = new MutexSecurity();
        securitySettings.AddAccessRule(allowEveryoneRule);
        mutex.SetAccessControl(securitySettings);
    }

    public SingleGlobalInstance(int timeOut)
    {
        InitMutex();
        try
        {
            if(timeOut < 0)
                hasHandle = mutex.WaitOne(Timeout.Infinite, false);
            else
                hasHandle = mutex.WaitOne(timeOut, false);

            if (hasHandle == false)
                throw new TimeoutException("Timeout waiting for exclusive access on SingleInstance");
        }
        catch (AbandonedMutexException)
        {
            hasHandle = true;
        }
    }


    public void Dispose()
    {
        if (mutex != null)
        {
            if (hasHandle)
                mutex.ReleaseMutex();
            mutex.Dispose();
        }
    }
}

then use like:

using (new SingleGlobalInstance(1000)) //1000ms timeout on global lock
{
    //Only 1 of these runs at a time
    GlobalNodeList.Remove(node)
}

Hope this saves you some time.

Examples related to concurrency

WAITING at sun.misc.Unsafe.park(Native Method) What is the Swift equivalent to Objective-C's "@synchronized"? Custom thread pool in Java 8 parallel stream How to check if another instance of my shell script is running How to use the CancellationToken property? What's the difference between a Future and a Promise? Why use a ReentrantLock if one can use synchronized(this)? NSOperation vs Grand Central Dispatch What's the difference between Thread start() and Runnable run() multiprocessing.Pool: When to use apply, apply_async or map?

Examples related to locking

How to detect query which holds the lock in Postgres? How to disable Home and other system buttons in Android? Git 'fatal: Unable to write new index file' Show all current locks from get_lock How to find out what is locking my tables? How to solve SQL Server Error 1222 i.e Unlock a SQL Server table Confused about UPDLOCK, HOLDLOCK How does lock work exactly? How to implement a lock in JavaScript LINK : fatal error LNK1104: cannot open file 'D:\...\MyProj.exe'

Examples related to mutex

What is the Swift equivalent to Objective-C's "@synchronized"? Mutex lock threads When should one use a spinlock instead of mutex? Is there a Mutex in Java? Mutex example / tutorial? When should we use mutex and when should we use semaphore Proper use of mutexes in Python Lock, mutex, semaphore... what's the difference? Example for boost shared_mutex (multiple reads/one write)? What is mutex and semaphore in Java ? What is the main difference?

Examples related to semaphore

semaphore implementation "The semaphore timeout period has expired" error for USB connection Semaphore vs. Monitors - what's the difference? Is there a Mutex in Java? When should we use mutex and when should we use semaphore Lock, mutex, semaphore... what's the difference? Delete all SYSTEM V shared memory and semaphores on UNIX-like systems What is mutex and semaphore in Java ? What is the main difference? Difference between binary semaphore and mutex What is a semaphore?