Saturday, April 24, 2010

Race Condition as Illustrated with Racer X and Speed Racer

Sometimes nothing works better than a simple example.

Below is a short program that demonstrates a race condition that occurs when two threads share some bit of state. It is written in C# and if you run it several times you should see inconsistent behaviors.

Sometimes Speed Racers thread finishes first and resets the SharedState to true and sometimes Racer X wins. This is the heart of threading problems, shared state and inconsistent results.

Now lets looks at a proposed fix. In RacerX there is a commented line
//System.Threading.Thread.Sleep(100);

By uncommenting it,  the inconsistent behaviour changes. Sometimes the program finishes because RacerX finished first and waited long enough for Speed Racer to finish. (You know he was the older brother and always looking out for Speed Racer)

But sometimes Speed Racer finishes first and he doesn't wait for RacerX. So Racer X keeps circling around. (Keep in mind Speed did not know that Racer X was his older brother)

So in this case it appears that the code has gotten better because the bug is now showing only half the time. But in reality it is just as flaky. The bug has now become intermittant and harder to reproduce.


class Program
{
static bool SharedState = true;

static void Main(string[] args)
{
Thread racerX = new Thread(RacerX);
racerX.Start();
Thread speedRacer = new Thread(SpeedRacer);
speedRacer.Start();
System.Threading.Thread.Sleep(2000);
SharedState = false;
}


static void RacerX()
{
while (SharedState)
{
Console.WriteLine("RacerX");
}
//System.Threading.Thread.Sleep(100);
SharedState = true;
}


static void SpeedRacer()
{
while (SharedState)
{
Console.WriteLine("SpeedRacer");
}
SharedState = true;
}
}

No comments: