Search code examples
c#multithreadinglockingvolatileinterlocked

Why this code works and not crashing


I was learning about volatile , interlock and lock in C#, Wrote below code to print odd and even numbers without using any of these synchronization construct, I ran this code several times and always gives proper answer,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace microsoft
{
    class th2_odd_event
    {
        static int num = 1;
        static bool guard = false;
        public void init()
        {
            Thread th = new Thread(print_odd);
            Thread th2 = new Thread(print_even);
            th.Start();
            th2.Start();

        }
        public static void print_odd()
        {
            while (true)
            {
                if (guard == false)
                {
                    if (num % 2 != 0)
                    {
                        Console.WriteLine(num);
                        num++;
                    }

                    guard = true;
                }
                if (num > 20)
                    break;
            }
        }

        public static void print_even()
        {
            while (true)
            {
                if (guard == true)
                {
                    if (num % 2 == 0)
                    {
                        Console.WriteLine(num);
                        num++;
                    }
                    guard = false;
                }

                if (num > 20)
                    break;
            }
        }

    }

How this code working ? Is it by luck , there is no clash between two thread ? I missing something...


Solution

  • haven't tried it out, but just by observation, it seems like the 2 threads are just running exclusive while loops, if you think of the 'guard' variable as the lock/mutex variable.

    when the odd thread is running the loop, the logic part is hit, only if the 'guard' is false. at this time, the even thread is just going to execute a no-op while loop, since the guard is not true. (read-only if checks are safe)

    finally when the odd thread sets the guard to true, it's own if check will return false and the even thread's if check will become true and it'll start printing the even number.

    the cycle then repeats and the threads work almost exclusively. the 'guard' variable is changed only at the end of the if block, in an atomic assignment and hence the 2 threads don't really collide.

    that is the reason you may be getting no issues.