C# Threading: Mutual exclusion (via Mutex Class)



Observe the following faulty snippet (don't use):

 
using System;
using System.Threading;
using System.IO;
 
class Program
{
    static void Main(string[] args)
    {
        for (int i = 0; i < 3; i++)
        {
            Thread thread = new Thread(new ThreadStart(ThreadMain));
            thread.Name = String.Concat("Thread - ", i);
            thread.Start();
        }
    }
 
    static void ThreadMain()
    {
        // Simulate Some work
        Thread.Sleep(500);
 
        // Access a shared resource / critical section
        WriteToFile();
    }
 
    static void WriteToFile()
    {
        String ThreadName = Thread.CurrentThread.Name;
        Console.WriteLine("{0} using resource", ThreadName);
 
        try
        {
            using (StreamWriter sw = new StreamWriter("1.txt", true))
            {
                sw.WriteLine(ThreadName);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}
 

What we've got here is three threads trying to write to a file, which fails horribly since we cant concurrently write to the same file.



We need some kind of synchronization mechanism to ensure that our threads access shared resources when appropriate.

In the .NET framework one of the solutions is to use the Mutex ("Mutual exclusion") class to aid us with this issue.

In the following snippet the issue gets resolved by adding a Mutex instance to it:

 
static Mutex mutex = new Mutex();
 
static void WriteToFile()
{
	mutex.WaitOne();
 
	String ThreadName = Thread.CurrentThread.Name;
	Console.WriteLine("{0} using resource", ThreadName);
 
	try
	{
		using (StreamWriter sw = new StreamWriter("1.txt", true))
		{
			sw.WriteLine(ThreadName);
		}
	}
	catch (Exception ex)
	{
		Console.WriteLine(ex.Message);
	}
 
	Console.WriteLine("{0} releasing resource", ThreadName);
 
	mutex.ReleaseMutex();
}
 

The first thread that reaches the critical section (writing of the file) takes ownership of the mutex - the other threads simply wait for the mutex to be released by the thread that owns it - each taking ownership once its released etc etc etc.

Basically its like making a queue behind a resource and only one thread is allowed to use the resource at a time.



We do however get a more lightweight class in the .NET framework that provides mutual-exclusion as well, namely the Monitor class (or lock statement).

What makes the Mutex class different (and more powerful) can be observed in the following snippet:

 
using System;
using System.Threading;
 
class Program
{
    static void Main(string[] args)
    {
        bool createdNew;
 
        using (Mutex mutex = new Mutex(true, "App", out createdNew))
        {
            if (!createdNew)
            {
                Console.WriteLine("Application already open");
                return;
            }
 
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
    }
}
 

Mutexes can be accessed system wide and across app domains & terminals, in the preceding snippet we prevent an user of opening multiple instances of our process.

There are two types of Mutexes, local(unnamed) - which is only available within its parent process (like the first snippet) and global(named) which is available system wide (like in the last snippet).

Additionally we can set the visibility of a global(named) mutex with regards to Terminal Services. If our named mutex starts with "Global\", it becomes visible to all terminal sessions, if it starts with "Local\" its only available to the terminal session that created it.

Additional reading:
C# Threading: Mutual exclusion (via Monitor Class)
http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx







Comments



Mutex abandoned prematurely

An abandoned mutex indicates a serious programming error. http://msdn.microsoft.com/en-us/library/system.threading.abandonedmutexexception.aspx Basically - you're required to explicitly release your mutex before the process that owns the mutex terminates - else it will result in an abandoned mutex exception. Which indicates that the process that owned the mutex might have prematurely ended - crashed etc. (or it was never released in code - but hey .net can't know for sure - so it assumes that something probably went wrong)


Mutex

The wait completed due to an abandoned mutex------- as i release the ownership of mutex by mutex.release(); i want to CREATE new mutex to run another process i wait for mutex ownership by mutex.waitone() but i m getting problem at mutex.waitone() The wait completed due to an abandoned mutex


Post comment

Name *
Email
Title
Body *
Security Code
*
* Required fields

Related Posts

C# Threading: Semaphore


2010-09-18 22:51:47

C# Threading: COM Apartment Model


2010-09-13 12:04:25

C# Threading: BackgroundWorker


2010-03-20 22:51:51

Latest Posts

Be the best stalker you can be


2011-12-13 22:33:54

Syntactic sugar (C#): Enum


2011-08-04 16:50:18

Top 5 posts

Simple WYSIWYG Editor


Creating a WYSIWYG textbox for your website is actually quite simple.
2007-02-01 12:00:00

Moving items between listboxes in ASP.net/PHP example


Move items between two listboxes in ASP.net(C#, VB.NET) and PHP
2008-06-12 17:07:43

Cross Browser Issues: Firefox Word Wrapping


Firefox word wrapping issues
2008-06-09 09:51:21

Populate a TreeView Control C#


Populate a TreeView control in a windows application.
2009-08-27 16:01:03

C# YouTube : Google API


Post on how to integrate with YouTube using the Google Data API
2011-03-12 08:37:51