Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 478
coffee Avatar asked Nov 12 '13 15:11

coffee


People also ask

What is QMutex?

The purpose of a QMutex is to protect an object, data structure or section of code so that only one thread can access it at a time (this is similar to the Java synchronized keyword).

Is QT multithreaded?

Qt offers many classes and functions for working with threads. Below are four different approaches that Qt programmers can use to implement multithreaded applications.


1 Answers

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();
like image 189
ratchet freak Avatar answered Oct 17 '22 06:10

ratchet freak