Csharp Code Samples

Rohan’s Blog – C# .NET Programming
  • rss
  • Home
  • About
  • Search
  • Contact Me

Thread Synchronization: Avoiding Race Conditions

Rohan Warang | April 5, 2009

Race conditions occur when two or more threads try to gain control of the same object. In a threaded application multiple instances of threads run concurrently. These threads may share some variables such as counters or some other global objects. There is every chance that multiple threads simultaneously try to write values to the same object. This is known as a race condition.

Race Conditions

Consider the example shown below. We have a variable result and there are 3 threads trying to write a unique value to it.

Show Code

class ProcessData
{
    int result = 0;
    public void Process()
    {
        Thread worker1 = new Thread(Work1);
        Thread worker2 = new Thread(Work2);
        Thread worker3 = new Thread(Work3);

        worker1.Start();
        worker2.Start();
        worker3.Start();

        Console.WriteLine(result);
    }

    void Work1() { result = 1; }
    void Work2() { result = 2; }
    void Work3() { result = 3; }
}

Looking at the code it might seem that the result at the end will be 3. But if you try executing the code you will find out that it is not always true. The result might be 1, 2 or even 0 if the main thread executes before others finish. The result is not predictable.

The reason for this is that the operating system decides which thread gets executed first. And the order in which we start the threads is not all that important. So thread that is given least priority by the operating system gets executed last.

For a more detailed explanation refer Threading on Multi-core CPUs.


The Solution

There are many ways in which you can avoid race conditions depending on the type of application you are writing. But the most common method that works in any condition is using Wait Handles and Signaling. In the above example we will try to ensure that the first thread is the last one that writes value to result variable.

The approach is quite simple we assume all threads are started at the same time. But the first thread is forced to wait till second and third thread signal that they are done.

Similarly the main thread is forced to wait till the first thread completes. This ensures that the Console.WriteLine() is not called before the other threads finish their work.

Show Code

class ProcessData
{
    int result = 0;

    AutoResetEvent event1 = new AutoResetEvent(false);
    AutoResetEvent event2 = new AutoResetEvent(false);
    AutoResetEvent event3 = new AutoResetEvent(false);

    public void Process()
    {
        Thread worker1 = new Thread(Work1);
        Thread worker2 = new Thread(Work2);
        Thread worker3 = new Thread(Work3);

        WaitHandle[] waitHandles = new WaitHandle[] { event2, event3 };

        worker1.Start();
        worker2.Start();
        worker3.Start();

        WaitHandle.WaitAny(new WaitHandle[] { event1 });
        Console.WriteLine(result);
    }

    void Work1()
    {
        WaitHandle.WaitAll(new WaitHandle[] { event2, event3 });
        result = 1;
        event1.Set();
    }

    void Work2() { result = 2; event2.Set(); }
    void Work3() { result = 3; event3.Set(); }
}

To achieve this we need to declare AutoResetEvents for each thread (except the main one). Whenever a thread finishes execution it signals its respective AutoResetEvent by calling Set(). The first thread waits for both second and third thread to signal and then starts execution.

Similarly the main thread waits for the first thread to signal before it prints the value. This method will always ensure that the final result is 1.

Download Sample
RaceConditionSample.zip

Categories
Tutorials
Tags
Race Condition, Synchronization, Threading, Wait Handles
Comments rss
Comments rss
Trackback
Trackback

« Asp.net Permalinks Using URL Rewriting Thread Synchronization: Ensuring Atomic Operations »

One Response to “Thread Synchronization: Avoiding Race Conditions”

  1. Redpiemi says:
    April 19, 2009 at 2:29 pm

    formidable site this csharp-codesamples.com rated to see you have what I am actually looking for here and this this post is exactly what I am interested in. I shall be pleased to become a regular visitor :)

Leave a Reply

Click here to cancel reply.

Spam protection by WP Captcha-Free

Subscribe

dZone

Categories

  • Optimization
  • Tutorials

Admin

  • Log in
Creative Commons License rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox