Click here to Skip to main content
Click here to Skip to main content

Thread Synchronization with Semaphore

By , 19 Nov 2011
 
Semaphore.JPG

Introduction

Semaphore is a synchronization technique where we can control number of threads to access a resource. In lock/Mutex, only one thread can access resources at a time. But Semaphore allows multiple threads to access the same resource at a time. We can limit the number of threads that can access the same resources. In this article, I have shown three different ways to access resources.

  • No-1. No Synchronization
  • No-2. Synchronization with Monitor
  • No-3. Synchronization with Semaphore

Using the Code

No Synchronization

With no synchronization, all threads run simultaneously and execute the same piece of code simultaneously. There is no restriction on how many threads can access it. Following is the code:

private void btnNoSync_Click(object sender, EventArgs e)
{
            listBox1.Items.Add("== No Synchronization ===========");
            int TotalThread = 5;
            Thread[] Threads = new Thread[TotalThread];
            for (int i = 0; i < TotalThread; i++)
            {
                Threads[i] = new Thread(new ThreadStart(AccessCode));
                Threads[i].IsBackground = true;
                Threads[i].Start();
            } 
}
public void AccessCode()
{
   listBox1.BeginInvoke(new ParameterizedThreadStart(UpdateUI), new object[] 
       {"Thread ID : " + Thread.CurrentThread.ManagedThreadId.ToString() + ": Entered" }
                        );
   Thread.Sleep(500);
   listBox1.BeginInvoke(new ParameterizedThreadStart(UpdateUI), new object[]  
       { "Thread ID : " + Thread.CurrentThread.ManagedThreadId.ToString() + " : Exit" }
                        );
}
 
// Following code is used to update UI
public void UpdateUI(object objOutput)
{
   listBox1.Items.Add(objOutput.ToString());
}

Synchronization with Monitor

Synchronization with monitor class, only one thread can access the same resource at a time. Thread is run simultaneously but it can access the block of code one at a time. There is a restriction on thread so that only a single thread can access a particular code block.

private void buttonMonitor_Click(object sender, EventArgs e)
{
            listBox1.Items.Add("== Using Monitor =============");
            int TotalThread = 5;
            Thread[] Threads = new Thread[TotalThread];
            for (int i = 0; i < TotalThread; i++)
            {
                Threads[i] = new Thread(new ThreadStart(AccessCodeWithMonitor));
                Threads[i].IsBackground = true;
                Threads[i].Start();
            }
} 
private void AccessCodeWithMonitor()
{
            Monitor.Enter(this);
            try
            {
                listBox1.BeginInvoke(new ParameterizedThreadStart(UpdateUI), new object[] 
                     { "Thread ID : " + 
		    Thread.CurrentThread.ManagedThreadId.ToString() + " : Entered" });
                Thread.Sleep(500);
                listBox1.BeginInvoke(new ParameterizedThreadStart(UpdateUI), new object[] 
                     { "Thread ID : " + 
		    Thread.CurrentThread.ManagedThreadId.ToString() + " : Exit" });
            }
            finally
            {
                Monitor.Exit(this);
            }
}
private void UpdateUI(object objOutput)
{
   listBox1.Items.Add(objOutput.ToString());
}

Synchronization with Semaphore

In synchronization with semaphore class, we can allow more than one thread to access the same block of code. Actually, we can specify how many threads can access the same block of code at the same time.

private void btnSemaphore_Click(object sender, EventArgs e)
{
            listBox1.Items.Add("== Using Semaphore =============");
            int TotalThread = 5;
            int SemaphoreCount = 3;
            Thread[] Threads = new Thread[TotalThread];
            Semaphore Sema = new Semaphore(SemaphoreCount, SemaphoreCount);
            for (int i = 0; i < TotalThread; i++)
            {
                Threads[i] = new Thread(new ParameterizedThreadStart
				(AccessCodewithSemaphore));
                Threads[i].IsBackground = true;
                Threads[i].Start(Sema);
            }
}
public void AccessCodewithSemaphore(object objSemaphore)
{
            bool IsComplete = false;
            Semaphore l_SemaPhore = (Semaphore)objSemaphore;
            while (!IsComplete)
            {
                if (l_SemaPhore.WaitOne(200, false))
                {
                  try
                  {
                    listBox1.BeginInvoke(new ParameterizedThreadStart(UpdateUI), 
					new object[] 
                      {"Thread ID : " + 
		    Thread.CurrentThread.ManagedThreadId.ToString() + " : Entered" });
                    Thread.Sleep(500);
                   }
                   finally
                   {
                     l_SemaPhore.Release();
                     listBox1.BeginInvoke(new ParameterizedThreadStart(UpdateUI), 
					new object[] 
                       { "Thread ID : " + 
		     Thread.CurrentThread.ManagedThreadId.ToString() + " : Exit" });
                     IsComplete = true;
                    }
                }
                else
                {
                  listBox1.BeginInvoke(new ParameterizedThreadStart(UpdateUI), 
					new object[] 
                  {"Thread ID :"+Thread.CurrentThread.ManagedThreadId.ToString() + 
				": Waiting To enter"});
                }
            }
} 
public void UpdateUI(object objOutput)
{
   listBox1.Items.Add(objOutput.ToString());
}

Testing the Code

Semaphore can be tested easily. Run the application and press all buttons one by one and see the effect of semaphore which controls the total number of threads that can execute some block of code simultaneously. Semaphore is a resource based synchronization technique and its system wide synchronization resource.

History

  • 19th November, 2011: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Pranjit Kalita
Software Developer Sapient Corporation Pvt. Ltd.
India India
Member
Software Devloper sience 2006. Experience on VB 6.0,C# Web, Windows and Distributed application like WCF etc. Currently working at Sapient Corporation Pvt. Ltd

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionMonitor.Wait and Monitor.Pulsemembersupercat921 Nov '11 - 12:09 
QuestionWhen one should use a semaphore?memberPaulo Zemek21 Nov '11 - 1:10 
I think the big question here is: When one needs to use a semaphore?
 
In fact, you compared a semaphore to a lock, but their purpose is very different.
Even if you can compare a lock as a semaphore that allows only one at a time, the lock exists to avoid that "incomplete" states are seen by other threads.
A very simple example can be shown by drawing lines to the screen using the old "MoveTo" and "DrawTo" functions.
If one thread does MoveTo 0, 0 and DrawTo 100, 0
While another one does MoveTo 0, 100 and DrawTo 100, 100 without synchronization, we may end up doing:
MoveTo 0, 0 - useless
MoveTo 0, 100
DrawTo 100, 0
DrawTo 100, 100
 
Which will give us a completely wrong result, all because an incomplete state was used. Using a semaphore will not help solve such problem.
 
So, what's the advantage of a semaphore?
In which cases do you believe one should use a semaphore? If it is not avoiding one thread to see incomplete states... what's its purpose?
I can say that I personally use semaphores to run many animations at once, limiting the amount of simultaneous threads to the number of processors... after all, having more threads running at the same time will only degrade performance.
Do you want to create a new programming language?
Do you want to know how to create a virtual machine?
Are at least interested on how they work?
So, see my article: POLAR

GeneralMy vote of 3memberNaerling19 Nov '11 - 3:15 
GeneralRe: My vote of 3memberPranjit Kalita24 Nov '11 - 3:53 
GeneralRe: My vote of 3memberNaerling24 Nov '11 - 7:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 19 Nov 2011
Article Copyright 2011 by Pranjit Kalita
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid