mercredi 26 mai 2021

Block multiple threads around an atomic variable. Best approach?

I am attempting to design a system in which I'll have multiple threads. All these threads share a common variable (which is atomic) at a time and when each thread starts it increments that variable and before that thread ends it decrements that variable. I would like a thread to block if the current value of that variable is greater than a specific limit value. A simple psuedocode is this:

std::atomic<int> var;
int limit = 3; //limit value
void doWork() //This method is run as multiple thread simultaneously
{
  if(var.load() < limit) 
  {
     //block until this condition is met
  }
  //increment
  var++;
  //Do some work
  .....
  //Decrement before leaving
  var--
}

Now two approaches come to my mind. The first approach is to sleep while var.load < limit but this looks sub-optimal. The second approach is to use conditional_variable. I am using that approach below but I believe I have two issues here

  1. The first thread will block on cv.wait(lk, []{return var.load() < limit});
  2. Multiple threads wont be doing work only one will do work while others will be blocked.

I would appreciate it if someone can suggest on how I can remove these defects from the code below or if there is a better approach ?

std::condition_variable cv;
std::mutex cv_m;
std::atomic<int> var;
int limit = 3; //limit value
void doWork()
{
  std::unique_lock<std::mutex> lk(cv_m);
  std::cerr << "Waiting... \n";
  cv.wait(lk, []{
         return var.load() < limit
        });
  //Increment var
   var++;
  //Do some Work
  ...
  //Decrement Work
  var--
  cv.notify_all();
}

Aucun commentaire:

Enregistrer un commentaire