coffee
coffee

Reputation: 713

Qt5 QWaitCondition example

I am getting myself familiar with QT5 concurrency library. I was looking at the QWaitCondition example (http://qt-project.org/doc/qt-5.0/qtcore/qwaitcondition.html#details).
Here, one thread (Thread B), reads user input, and all other threads (Thread A) process this input.

Thread A:

forever {
    mutex.lock();
    keyPressed.wait(&mutex);
    ++count;
    mutex.unlock();

    do_something();

    mutex.lock();
    --count;
    mutex.unlock();
}

Thread B:

forever {
    getchar();

    mutex.lock();
    // Sleep until there are no busy worker threads
    while (count > 0) {
        mutex.unlock();
        sleep(1);
        mutex.lock();
    }
    keyPressed.wakeAll();
    mutex.unlock();
}

The reason for using count variable and the extensive mutex synchronization is to prevent symbols loss.
The problem is, I think there is still a chance that a symbol will get lost: imagine the following scenario:

  1. Thread A processes a symbol, and decreases the countes (--count); the mutex is released; then Thread A stops

  2. Thread B returns from sleep, aquires the mutex, sees, that count == 0, and calls keyPressed.wakeAll(), and then unlocks the mutex. However, the wakeAll() call goes to nowhere, since the Thread A is not waiting.

  3. Thread A starts again, aquaires the mutex and goes into wait(). Since wakeAll() was already called, the symbol is lost.

Am I right, or am I missing something? If I am right, how to correct the example to really prevent it from skipping the symbols?

Upvotes: 7

Views: 10942

Answers (1)

ratchet freak
ratchet freak

Reputation: 48226

you are right

to fix this the loop should be entered with the mutex already acquired:

mutex.lock();
forever {

    keyPressed.wait(&mutex);
    ++count;
    mutex.unlock();

    do_something();

    mutex.lock();
    --count;

}
mutex.unlock();

Upvotes: 11

Related Questions