Synchronous Threading

Once again, it's IPL, and it was Pollard who was batting. But this time, I did watch him. I did a congrats Tweet to him too before writing this code for the article. Well this article is basically to explain how to make threads run synchronously.

There are times in everyone's life when they need to do synchronization via two or more threads. Before proceeding, one may ask what is synchronization? So before they ask that question, here is the basic idea of what it actually is.

Synchronous Operations

The best real-world example that I can think of for explaining synchronization is when you are cooking. Imagine you are cooking Shaahi Paneer (the most tasty Indian Dish, I just love it). Also imagine that you have a gas stove with 4 burners. Now the recipe of the dish says:

  1. First you need to cut the cheese (paneer) into small pieces.
  2. Put a frying pan with oil on a burner to get it hot.
  3. Put the cheese pieces into the pan and fry them until they are fried properly.
  4. Once they are fried, put them into the gravy that have been prepared before (how to prepare gravy is out of the scope of this article).

Now as you might observe, Step 1 and Step 2 can be done in parallel. That is to say you can do both, cutting the cheese and warming the pan, simultaneously. These are called Asynchronous Operations since they can be done in parallel, having nothing to do with one another.

But for the Step 3 of course, you need both Step 1 and Step 2 to be complete. You cannot proceed to frying the cheese until the oil is warm and the cheese has been cut into pieces. Task 3 therefore can be described as a synchronous task. You need to stop until both the preceding steps finish.

Similarly you cannot proceed into Step 4 until you are done with Step 3. Step 4 therefore is also a synchronous operation.

How does it all look in code?

Just for the sake of brevity, let us assume that all the preceding four steps are carried out by four different threads.

In order to stop the execution of the threads, we need a class AutoResetEvent.

readonly AutoResetEvent m_autoreset = new AutoResetEvent(false);

Here is the entire code for my Cheese Program above:

class Program
{
    readonly AutoResetEvent m_autoreset = new AutoResetEvent(false);
    static void Main(string[] args)
    {
        var me =
new Program();

        var cutCheese =
new Thread(me.CutCheese);
        var warmOil =
new Thread(me.WarmOil);
        var frCheese =
new Thread(me.FrCheese);
        var addToGravy =
new Thread(me.AddToGravy);

        cutCheese.Start();
        warmOil.Start();
        
//Wait for above process to complete
        
me.m_autoreset.WaitOne();
        frCheese.Start();
        me.m_autoreset.WaitOne();
        addToGravy.Start();
    }
 
   
private void CutCheese()
    {
    }
   
private void WarmOil()
    {
        var me =
new Program();
       //Reset the wait process
       me.m_autoreset.Set();
    }
   
private void FrCheese()
    {
        var me =
new Program();
      
//Reset the wait process
       me.m_autoreset.Set();
    }
   
private void AddToGravy()
    {
    }
}

The line "me.m_autoreset.WaitOne();" will stop the execution of the code and keep it there until "me.m_autoreset.Set();" is called. The two threads, cutCheese and warmOil will start and further execution will be blocked until both are complete. Once done, the execution will resume, and henceforth.

The process therefore suggests that you can even process the asynchronous process synchronously. And at the end of the day, you will get a very good dish to eat.

Happy reading!!!