[SOLVED]QMutex not working at same way on Windows and Linux



  • I'm developing a code to run in a separate thread for testing and i'm using a QMutexLocker to lock it
    code:

    @
    QFuture<void>t1;
    QMutex mutex;
    int num;

    void MainWindow::thread1()
    {
    QMutexLocker locker(&mutex);
    locker.mutex()->lock();
    num++;
    qDebug() << "Thread unlocked " + QString::number(num);
    }

    void MainWindow::on_pushButton_clicked()
    {
    if (!t1.isRunning())
    {
    t1 = QtConcurrent::run(this, &MainWindow::thread1);
    }
    }

    void MainWindow::on_pushButton_2_clicked()
    {
    mutex.unlock();
    }
    @

    The problem is: if I call push Button 2 before call push Button 1, in other words, if I unlock the thread before start it, on Windows i get: "Thread unlocked" but on Linux nothing happens. Why? And how to do the QMutex work at the same way both Windows and Linux?



  • The problem may be in this code:
    @ QMutexLocker locker(&mutex);
    locker.mutex()->lock(); //Not needed!@

    The constructor of QMutexLocker will already lock the mutex, no need to lock a mutex you already locked!

    Also, from what I can see, the "main" thread never locked the mutex, so what is on_pushButton_2_clicked() supposed to do? Only a thread that has locked (taken ownership of) a mutex can unlock that mutex again...



  • What you mean? I can't use QMutex across threads? If yes is there any way to lock/unlock some thread from another thread? Because is it that i'm looking for.



  • What I mean is: You can use a mutex across multiple threads. Different threads can try to lock the same mutex. If thread A tries to lock the mutex, while the mutex already is locked by thread B, then thread A will be blocked at this point until thread B unlocks the mutex. But: A can not unlock a mutex that is currently locked/owned by B.

    bq. void QMutex::unlock ()
    Unlocks the mutex. Attempting to unlock a mutex in a different thread to the one that locked it results in an error. Unlocking a mutex that is not locked results in undefined behavior.

    So you are probably looking for a (binary) semaphore or a conditional variable here...

    See also:
    http://doc.qt.digia.com/qt/qsemaphore.html



  • QSemaphore can be used across threads without any problem? If yes my question is solved!



  • Yes, the thread which acquire()'s a Semaphore does not take ownership, in the sense of a Mutex. If the Semaphore is zero while one thread calls acquire(), it will get blocked. Another thread can then call release() on the Semaphore to unblock the waiting thread. The thread who calls release() does not need to have called acquire() before. In contrast to a conditional variable, the Semaphore will "remember" the release() if no thread is currently waiting, so the next acquire() won't block. With a conditional variable, if you call wakeOne() while no other thread is waiting, the "wake" gets lost! Depends on your individual problem which one you need.

    Typical example for use of Semaphores is the "consumer/producer" pattern:
    http://en.wikipedia.org/wiki/Semaphore_(programming)#Example:_Producer.2Fconsumer_problem



  • Thanks, your reply is very helpful!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.