0

How come the following doesn't give me a read / write error ever? In my main thread I increment i, which is a read, and a write. In both threads I write to total. I would expect to see an error, but I leave it running and never get one, why is this?

For reference, my computer has 2 cores, 4 logical cores, its an Intel i3.

using System;
using System.Collections.Generic;
using System.Threading;

namespace Threading001
{
    class Program
    {

        static void Main(string[] args)
        {
            int i = 0;
            int total = 0;

            new Thread(() => {
                var service2 = new Service();
                while (true)
                {
                    try
                    {
                        total += i;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error from thread 2: {0}", ex);
                        break;
                    }
                }
            }).Start();

            while (true)
            {
                try
                {
                    total += i;
                    i++;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error from thread 1: {0}", ex);
                    break;
                }
            }
        }

    }
}
user1515024
  • 181
  • 9
  • 3
    What error you expecting and why there should be an error? – Rohit Vats Dec 29 '13 at 11:55
  • You will need to write code with a predicable (single-threaded) value for 'total' and then you may see deviation with threading. – H H Dec 29 '13 at 12:13

2 Answers2

1

Since both threads may update total at the same time, the error you may get is a "corrupted" total. i.e.: that total doesn't contain the "correct" sum. However, it won't throw an Exception.

If you want to do this kind of things and avoid any potential error, you could use Interlocked.Add:

Interlocked.Add(ref total, i)

Here is a simplified example:

using System;
using System.Collections.Generic;
using System.Threading;

namespace Threading001
{
  class Program
  {

    static void Main(string[] args)
    {
        int total = 0;

        Thread thread = new Thread(() => {
            for ( int j=0 ; j < 1000000 ; j++)
            {
                Interlocked.Add(ref total, 1);
                //total++; //not thread-safe
            }
        });
        thread.Start();

        for ( int i=0 ; i < 1000000 ; i++)
        {
            Interlocked.Add(ref total, 1);
            //total++; //not thread-safe
        }

        thread.Join();

        Console.WriteLine(total);
    }
  }
}

With the version not thread safe, I get a different total each time (eg: 1425407, 1109498, ...).

With the thread safe version, I get 2000000 every time.

So, conclusion: if both threads try to write at the same time, I won't get the results I want. However, it won't throw an exception.

gturri
  • 13,807
  • 9
  • 40
  • 57
0

race condition does not throw an exception.

http://en.wikipedia.org/wiki/Race_condition

notice the Example

here is the question in a "correct" manner

pthreads: If I increment a global from two different threads, can there be sync issues?

Community
  • 1
  • 1
Nahum
  • 6,959
  • 12
  • 48
  • 69
  • he has 2 threads increasing same variable. and he asks why he does not get an exception. – Nahum Dec 29 '13 at 12:10
  • Thanks Nahum, your answer was really good, and cleared up miss-assumptions I had about this example. The example on the Wiki page was spot on! But I also liked gturri's answer, and alas I can only pick one answer. – user1515024 Dec 29 '13 at 12:31
  • Sure. you should take time and take Modern Operating Systems Course. https://docs.google.com/viewer?url=http%3A%2F%2Fit.tdt.edu.vn%2F~tttin%2Fgiangday%2FHDH%2FModern%2520Operating%2520Systems.pdf is the book they use in the university I attend. – Nahum Dec 29 '13 at 12:40