jeudi 16 juin 2022

if there is race condition between notify_one?

global:
map<int,int> m;
mutex mut;
condition_variable cv;

thread1:
{
  unique_lock<mutex> lck(mut);
  cv.wait(mutex, []{m.size()>0});
  ...loop m...
}

thread2:
{
  for i in 100:
  {
    lock_guard<mutex> lck(mut);
    m.insert()
  }
  cv.notify_one()
}

Q1:Will my codes work fine and make m threadsafe?

Q2:If there is another thread3

thread3:
{
  {
    lock_guard<mutex> lck(mut);
    m.clear()
  }
  cv.notify_one()
}

Would there be a sequence like(depend on when the mutex unblocked)

thread2 insert ...
thread2 insert ...
thread3 clear...
thread2 insert ...
thread2 insert ...
thread3 notify_one ...
thread2 insert ...
thread2 notify_one ...

Even if I change thread2 into

{
  {
    //protect insert as a whole
    lock_guard<mutex> lck(mut);
    for i in 100:
    {
      m.insert()
    }
  }
  cv.notify_one()
}

Is there still a chance like

thread2 insert as a whole...
thread3 clear...
thread3 notify_one ...
thread2 notify_one ...

And that will make thread1 gets nothing when any notify_one comes.

What I intend to do is thread2's change into m could fully passed to thread1 without other thread's influence(such as thread3). If my codes not threadsafe, then what's the proper one?

Aucun commentaire:

Enregistrer un commentaire