1

Suppose we have four threads in this order (D, C, B, A) waiting in a queue, and 'r.cv.notify_all()' just gets invoked, and suppose thread A (first thread in the queue) locks the mutex and the lambda returns true, after thread A reaches the end of the while loop, the lock is going to be released as it follows the RAII rule so my question is if the lock gets released at the end of the loop, is thread B going to acquire it, or still the lock belongs to thread A (as its job hasn't finished yet)

void operator() (SharedData& r, std::chrono::system_clock::time_point tToc)
{
    
    unsigned short tempValue = r.value;
    Debug::out("Befooooooooooooooooooreee \n");
    while (std::chrono::system_clock::now() < tToc)
    {

        std::unique_lock<std::mutex> lock(r.mtx); // ---> "A B C D" four threads
        if (r.cv.wait_until(lock, tToc, [&]


            {
                Debug::out("TEstttttttt -> temp %x \n", tempValue);
                Debug::out("TEstttttttt -> value %x \n", r.value);          
                return (r.value != 0 && r.value != tempValue);              
            }


        ))

        {

            r.complement = ~(r.value);          
            Debug::out("AAAAAAAfterrrrrrrrrrfrrrr \n");
            tempValue = r.value;
            
        }
            
    }
}
Sami
  • 513
  • 4
  • 11
  • There is no queue (implies an ordering) waiting for a mutex. There is no fairness. The thread that locks the mutex next is determined by the OS with no guarantee as to which of the waiting threads locks it next. – Richard Critten Nov 25 '22 at 16:20
  • That's why I said 'supposed'. I know only OS decides which thread should be served first. But when thread A is served, the rest threads waiting for mutex will be served next right? any chance thread A gets served again? – Sami Nov 25 '22 at 16:26
  • 1
    If `A` still has some of it's time-slice left there is a good chance it will get the mutex next before other threads get scheduled. Google "mutex starvation" . A fair mutex can be implemented using the basic building blocks provided by the language and OS but it's a non-trivial task. – Richard Critten Nov 25 '22 at 16:30

1 Answers1

1

after thread A reaches the end of the while loop, the lock is going to be released ...

... and, that's it. That's the end of the story. The lock is released. We're outta here.

... or still the lock belongs to thread A

No, it does not belong to any thread. We've just determined that the lock is released. A released lock, by definition, is no longer locked. It is no longer owned by any execution thread.

Once the lock is released it's up for grabs to be locked by any other thread, either an execution thread that decided to lock it, for some reason, or an execution thread that was patiently waiting to acquire the lock, but could not (because some other execution thread was hoarding it).

So, presuming that the locking semantics are internally implemented in the manner you described: the next thread will acquire the lock.

... (as its job hasn't finished yet)

Whatever the thread's high level "job" is, and whether that high level job is finished, or not, is immaterial. The only thing that matters, when it comes to locking semantics, is: is the mutex locked or not. That's it. Mutexes are just small, low-level peons. They have no clue whatsoever, what might be some high level "job" that they're task to accomplish. They are just a cog in a wheel. All they know is whether they are locked, or not. That's it.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148