Dave
Dave

Reputation: 2984

How to make a threading race situation

For some reasons, I want to create a race problem with 2 threads. I thought that the race problem was caused when 2 threads that didn't lock the shared resource were running at the same time... which is what I'm trying to code. But the output is correct, and I want it to be wrong.

My shared resource is a static variable in a static class.

The problem is that it correctly outputs 1200. I know it sounds weird but I am trying to understand how to create/solve that kind of problem.

In my book, concepts of programming languages, it talks theoretically about such a problem.

The question is : How do I make it so this code produce random problems caused by my two threads accessing the same shared resource ?

public static class BankAccount
{
    public static int solde = 0;

}

public class Program
{
    static void Main(string[] args)
    {
        BankAccount.solde = 1000;

        Thread t = new Thread(up);
        Thread t2 = new Thread(down);


        t.Start();
        t2.Start();
        t.Join();
        t2.Join();


        Console.Write(BankAccount.solde);

        Console.Read();
    }

    static void up()
    {

        for (int i = 0; i < 500; i++)
        {
            BankAccount.solde++;
        }
    }

    static void down()
    {
        for (int i = 0; i < 300; i++)
        {
            BankAccount.solde--;
        }
    }

}

Upvotes: 2

Views: 143

Answers (2)

Baldrick
Baldrick

Reputation: 11840

It does race, you're just not running it enough times.

Try this main method instead.

It tries repeatedly and shows you when it fails, and how many runs it took to get a failure:

static void Main(string[] args)
{
    var runCount = 0;
    do
    {
        BankAccount.solde = 1000;
        runCount++;
        Thread t = new Thread(up);
        Thread t2 = new Thread(down);

        t.Start();
        t2.Start();
        t.Join();
        t2.Join();
    } 
    while (BankAccount.solde == 1200);


    Console.Write(BankAccount.solde + ": Run: " + runCount);

    Console.Read();
}

Output for me in debugger:

1201: Run: 36

Running in release mode with optimizations, it rarely races (because the code in the each thread runs so fast, thread 1 normally finishes before thread 2 even starts), but it still happens occasionally:

1414: Run: 168804

If you want it to race much more frequently, change your 'up' loop to iterate 50000 times, and your 'down' loop to iterate 49800 times.

Then you get crazy results like this (release mode, outside debugger):

-1198: Run: 12

This most likely happens when the decrements interleave persistently with the increments, such that in many cases, only the decrements are actually applied to the variable.

Upvotes: 3

Scott Hunter
Scott Hunter

Reputation: 49803

Do more of something more complicated; your critical sections are very small, which reduces the probability getting a bad interleaving, and the more times you enter them, the more likely you'll get a 'problem'.

Upvotes: 0

Related Questions