Click here to Skip to main content
15,885,435 members
Articles / General Programming / Threads
Article

Thread Synchronization with Semaphore

Rate me:
Please Sign up or sign in to vote.
4.00/5 (5 votes)
19 Nov 2011CPOL1 min read 54.9K   1.6K   31   5
An introduction to semaphore in contrast to Monitor
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:

C#
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.

C#
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.

C#
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)


Written By
Software Developer Sapient Corporation Pvt. Ltd.
India India
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

Comments and Discussions

 
QuestionMonitor.Wait and Monitor.Pulse Pin
supercat921-Nov-11 12:09
supercat921-Nov-11 12:09 
QuestionWhen one should use a semaphore? Pin
Paulo Zemek21-Nov-11 1:10
mvaPaulo Zemek21-Nov-11 1:10 
GeneralMy vote of 3 Pin
Sander Rossel19-Nov-11 3:15
professionalSander Rossel19-Nov-11 3:15 
GeneralRe: My vote of 3 Pin
Pranjit Kalita24-Nov-11 3:53
Pranjit Kalita24-Nov-11 3:53 
GeneralRe: My vote of 3 Pin
Sander Rossel24-Nov-11 7:05
professionalSander Rossel24-Nov-11 7:05 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.