Sergei
Sergei

Reputation: 550

Will consumer thread receive condition_variable notify signal if spuriously woken up

We know that condition variables a subject to spurious wake ups. Let's assume we have a 1-producer-1-consumer queue synchronized with a mutex and condition variable. The consumer thread gets a spurious wake up. The question is - will the consumer thread miss the notify signal from the producer? I understand it's extremely unlikely.. but is it still possible to lose the last element in the queue with such implementation?

Upvotes: 2

Views: 377

Answers (2)

Pete Becker
Pete Becker

Reputation: 76315

If the code that calls wait() isn't written right, it could, indeed, miss a wake up. But that would be a bit perverse. The usual idiom is:

lock the mutex
while the condition is not satisfied
    wait on the condition variable

the signaling thread should lock the mutex before signaling:

lock the mutex
signal the condition variable

Waiting on the condition variable unlocks the mutex for the duration of the wait. When the wait call returns, though, the mutex will be locked. So on a spurious wake up, the waiting thread will hold the mutex until it resumes waiting. While the waiting thread holds the mutex, the signaling thread can't signal the condition variable. When the waiting thread actually waits, the mutex gets unlocked and the signaling thread can go ahead and signal; the waiting thread will get the signal, and once the signaling thread releases the mutex, the waiting thread will resume execution.

So, no, proper code won't miss a signal. But if the waiting thread releases the mutex and reacquires it in the course of checking its condition, the signal could occur before the waiting thread calls wait, and the signal will be lost. Don't do that. <g>

Upvotes: 3

didiz
didiz

Reputation: 1099

Spurious wake up means it might wake up spuriously and then have to continue waiting.

It does not refer at all to the possibility of missing an event, for it would be useless if that were true.

This link provides a detailed explanation of cv and the wait method:

https://www.codeproject.com/Articles/598695/Cplusplus-threads-locks-and-condition-variables

 // print a starting message
    {
        std::unique_lock<std::mutex> locker(g_lockprint);
        std::cout << "[logger]\trunning..." << std::endl;
    }

    // loop until end is signaled
    while(!g_done)
    {
        std::unique_lock<std::mutex> locker(g_lockqueue);

        g_queuecheck.wait(locker, [&](){return !g_codes.empty();});

        // if there are error codes in the queue process them
        while(!g_codes.empty())
        {
            std::unique_lock<std::mutex> locker(g_lockprint);
            std::cout << "[logger]\tprocessing error:  " << g_codes.front() << std::endl;
            g_codes.pop();
        }
    }

Upvotes: 1

Related Questions