c++multithreadingunique-lock

waiting threads status while mutex gets released at the end of a loop in wait_for function in C++


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;
            
        }
            
    }
}

Solution

  • 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.