vendredi 25 mai 2018

Unable to starve writer thread in reader-writer scenario

Reader-Writer problem:

I have implemented a very basic version of reader-writer problem with the following conditions:

  1. Multiple readers are allowed to read data at a time.
  2. Only 1 writer is allowed to update data at a time.
  3. When readers are reading,then, writer cannot acquire access to the data.

I am doing the following in my code:

  • I am launching reader thread in every 10 milliseconds. Whereas,
  • I am launching writer thread in every 2 seconds.

So, that means, my writer should have starved but this is not happening.

Can somebody explains:

  1. Why writers are not getting starved?
  2. How to starve writer(where is the mistake in my code)?

Code:

#include <iostream>
#include "windows.h"
#include "vector"
#include "mutex"
using namespace std;


int dataa = 0; // shared resource
mutex _mData; // mutex to protect shared resource

mutex _mReaders;
int totalReaderThreads = 0;

void sharedPrint(string threadName, std::thread::id threadID, int dataa)
{
    cout << threadName.c_str() << "[" << threadID << "]. data[" << dataa << "]" << endl;
}

void producer()
{
    _mData.lock(); //Allow only 1 writer at a time to access shared resource:
    //<<critical-section-begin>>
        dataa++; //update data
        sharedPrint("Writer Thread", this_thread::get_id(), dataa);
    //<<critical-section-end>

    _mData.unlock();
}


void consumer()
{
    unique_lock<mutex> ul(_mReaders); //Allow only one reader

    //<<critical-section-begin>>
        totalReaderThreads++;
        if (totalReaderThreads == 1)
        {
            _mData.lock();//lock the data from writers
        }
    //<<critical-section-end>
    ul.unlock();


    //Allow all reader threads:
    int i = dataa; //Readers reading data
    sharedPrint("Reader Thread", this_thread::get_id(), i);


    ul.lock();  //Allow only one reader
    //<<critical-section-begin>>
        totalReaderThreads--;
        if (totalReaderThreads == 0)
        {
            _mData.unlock();//unlock the data for writers
        }
    //<<critical-section-end>
    ul.unlock();
}

void runConsumers()
{
    vector<thread> con;
    int counterr = 1;
    int seconds_ = 10;
    while (counterr)
    {

        Sleep(seconds_);// A new reader will attempt to read data in every 10 milliseconds.
        con.push_back(thread(consumer));
    }
    //joining consumers:
    for (int i = 0; i < 10; i++)
        con[i].join();
}

void runProducers()
{
    vector<thread> pro;
    for (int i = 0; i < 10; i++)
    {

        Sleep(2000); //A new producer will attempt to write data in every 2 seconds.
        pro.push_back(thread(producer));
    }
    //joining producers:
    for (int i = 0; i < 10; i++)
    {
        pro[i].join();
    }
}

int main()
{
    thread t1(runProducers);
    thread t2(runConsumers);

    t1.join();
    t2.join();

    getchar();
    return 0;
}

Aucun commentaire:

Enregistrer un commentaire