0

I am working on a program where multiple threads share common resource and thus synchronization is must while modifying this common resource.

Basic requirement:

  • if one thread is writing, other thread (reader/writer) should wait till first complete
  • if one thread is reading, other thread should wait if it is writer else if it can read data without waiting for first to complete

For that I have created a sample program with two Reader threads and tow Writer threads and implemented lock on reading and writing the common resource (in example a string).

It is like below.

    object lockObj;
    private string commonString;

    public string CommonResource
    {
        get
        {
            lock (lockObj)
            {
                //adding sleep to magnify error condition when reading takes longer time
                Thread.Sleep(1000 * 2); 
                return commonString;
            }
        }
        set
        {
            lock (lockObj)
            {
                Thread.Sleep(1000 * 5);
                commonString = value;
            }
        }
    }

it works fine in restricting two simultaneous reading-writing or writing-writing, but it also restrict two simultaneous reading-reading on common data (which is not required and makes reading unnecessarily slow).

I can implement this by having addition Boolean flags which keeps track of reading and writing process and update their selves accordingly. like below

But I would prefer internal mechanism first (if any) to achieve this instead of creating my own way.

    bool isReadingInProgress = false;
    bool isWritingInProgress = false;
    public string ReadData()
    {
        string val;
        while (isWritingInProgress)
        {
            Thread.Sleep(10);
        }
        isReadingInProgress = true;
        val = commonString;
        Thread.Sleep(2 * 1000);
        isReadingInProgress = false;
        return val;
    }

    public void WriteData(string val)
    {
        while(isReadingInProgress || isWritingInProgress)
        {
            Thread.Sleep(10);
        }
        isWritingInProgress = true;
        commonString = val;
        Thread.Sleep(5 * 1000);
        isWritingInProgress = false;
    }

I am not comfortable on above code as then dependency on Boolean flags will be very high, when they two are in fact just a common resources (like string for which i want synchronization) for threads. So i have to make these Boolean thread safe too (correct me if i m wrong).

Is there any better approach to do this?

If no, should i go with locking (as i shown in first code) and have slow reading function or i should go with this Boolean without bothering to make them thread safe?

calling of this threads are like below

static void Main(string[] args)
{
    commonResourceClass = new CommonResourceClass(); //class which holds data
    Thread writerThread1 = new Thread(() => WriterThreadRunner("writer 1"));
    Thread writerThread2 = new Thread(() => WriterThreadRunner("writer 2"));
    Thread readerThread1 = new Thread(() => ReaderThreadRunner("reader 1"));
    Thread readerThread2 = new Thread(() => ReaderThreadRunner("reader 2"));
    writerThread1.Start();
    readerThread1.Start();
    writerThread2.Start();
    readerThread2.Start();
}

static void WriterThreadRunner(string threadName)
{
    while (true)
    {
        //commonResourceClass.CommonResource = "Written";
        commonResourceClass.WriteData("Written");
    }
}

static void ReaderThreadRunner(string threadName)
{
    while (true)
    {
        //string Data = commonResourceClass.CommonResource;
        string Data = commonResourceClass.ReadData();
    }
}
Amit
  • 1,821
  • 1
  • 17
  • 30
  • 2
    Check [`ReaderWriterLockSlim`](https://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim(v=vs.110).aspx). And [a related question here](https://stackoverflow.com/questions/4217398/when-is-readerwriterlockslim-better-than-a-simple-lock). – mshsayem May 24 '18 at 03:14
  • @mshsayem this seems to be solving my concern. let me understand that in detail – Amit May 24 '18 at 03:17

0 Answers0